GoDasturchi
Why Generics? The Problem They Solve

Why Generics? The Problem They Solve

Nega generics? Ular yechadigan muammo

Composite Types kursida Sumga o'xshash funksiyalarni yozganingizda, u faqat bitta tur bilan ishlagan — masalan, faqat []int bilan. Agar []float64 uchun ham xuddi shunday yig'indi kerak bo'lsa-chi? Generics'siz sizda ikkita yomon variant bor edi.

example.go
func SumInts(nums []int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}

func SumFloats(nums []float64) float64 {
    total := 0.0
    for _, n := range nums {
        total += n
    }
    return total
}
// Ikkala funksiya ham bir xil mantiqni takrorlaydi — faqat tur farq qiladi.

Birinchi variant — kodni nusxalash: yuqoridagidek, har bir tur uchun alohida funksiya. Ishlaydi, lekin mantiqni o'zgartirish kerak bo'lsa, uni har joyda alohida-alohida o'zgartirishga to'g'ri keladi. Ikkinchi variant — Interfaces & Polymorphism kursidagi any (interface{})dan foydalanish:

example.go
func SumAny(nums []any) any {
    // Bu yerda "+" operatorini ishlatib bo'lmaydi —
    // Go nums ichida qanday tur borligini oldindan bilmaydi.
    // Har bir elementni type assertion bilan tekshirish kerak bo'lardi.
}

any moslashuvchan, lekin tur xavfsizligini yo'qotadi: kompilyator sizga yordam bera olmaydi, va noto'g'ri turdagi qiymat kiritilsa, xato faqat ishga tushirish vaqtida (runtime'da) chiqadi. Generics — bu ikki yomonlik orasidagi yechim: bitta funksiya yozasiz, lekin u chaqirilgan vaqtda aniq, tekshirilgan tur bilan ishlaydi — kodni nusxalamasdan ham, tur xavfsizligini yo'qotmasdan ham.

example.go
func Sum[T int | float64](nums []T) T {
    var total T
    for _, n := range nums {
        total += n
    }
    return total
}
// Bitta funksiya, ikkala tur bilan ham tur-xavfsiz ishlaydi.

Keyingi darslarda siz [T ...] sintaksisini, cheklovlarni (constraints) va generic struct'larni bosqichma-bosqich o'rganasiz — barchasi shu bitta muammoni yechish uchun: kodni nusxalamasdan, tur xavfsizligini saqlab qolgan holda qayta ishlatish.

Key Takeaway

Key Takeaway:

Generics'siz sizda ikki yomon variant bor: har bir tur uchun kodni nusxalash (takrorlanuvchi, lekin tur-xavfsiz), yoki any ishlatish (moslashuvchan, lekin tur xavfsizligisiz). Generics ikkalasining ham yaxshi tomonini beradi: bir marta yoziladigan, tur-xavfsiz kod.

NEXT UP

Generic Functions

Why Generics? The Problem They Solve

Nega generics? Ular yechadigan muammo

Composite Types kursida Sumga o'xshash funksiyalarni yozganingizda, u faqat bitta tur bilan ishlagan — masalan, faqat []int bilan. Agar []float64 uchun ham xuddi shunday yig'indi kerak bo'lsa-chi? Generics'siz sizda ikkita yomon variant bor edi.

example.go
func SumInts(nums []int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}

func SumFloats(nums []float64) float64 {
    total := 0.0
    for _, n := range nums {
        total += n
    }
    return total
}
// Ikkala funksiya ham bir xil mantiqni takrorlaydi — faqat tur farq qiladi.

Birinchi variant — kodni nusxalash: yuqoridagidek, har bir tur uchun alohida funksiya. Ishlaydi, lekin mantiqni o'zgartirish kerak bo'lsa, uni har joyda alohida-alohida o'zgartirishga to'g'ri keladi. Ikkinchi variant — Interfaces & Polymorphism kursidagi any (interface{})dan foydalanish:

example.go
func SumAny(nums []any) any {
    // Bu yerda "+" operatorini ishlatib bo'lmaydi —
    // Go nums ichida qanday tur borligini oldindan bilmaydi.
    // Har bir elementni type assertion bilan tekshirish kerak bo'lardi.
}

any moslashuvchan, lekin tur xavfsizligini yo'qotadi: kompilyator sizga yordam bera olmaydi, va noto'g'ri turdagi qiymat kiritilsa, xato faqat ishga tushirish vaqtida (runtime'da) chiqadi. Generics — bu ikki yomonlik orasidagi yechim: bitta funksiya yozasiz, lekin u chaqirilgan vaqtda aniq, tekshirilgan tur bilan ishlaydi — kodni nusxalamasdan ham, tur xavfsizligini yo'qotmasdan ham.

example.go
func Sum[T int | float64](nums []T) T {
    var total T
    for _, n := range nums {
        total += n
    }
    return total
}
// Bitta funksiya, ikkala tur bilan ham tur-xavfsiz ishlaydi.

Keyingi darslarda siz [T ...] sintaksisini, cheklovlarni (constraints) va generic struct'larni bosqichma-bosqich o'rganasiz — barchasi shu bitta muammoni yechish uchun: kodni nusxalamasdan, tur xavfsizligini saqlab qolgan holda qayta ishlatish.

Key Takeaway

Key Takeaway:

Generics'siz sizda ikki yomon variant bor: har bir tur uchun kodni nusxalash (takrorlanuvchi, lekin tur-xavfsiz), yoki any ishlatish (moslashuvchan, lekin tur xavfsizligisiz). Generics ikkalasining ham yaxshi tomonini beradi: bir marta yoziladigan, tur-xavfsiz kod.

NEXT UP

Generic Functions