Skip to content

018. Generics

Generics

Generics – bu turga bog'liq bo'lmagan va qayta ishlatiladigan kod yozish usuli bo'lib, dasturchilarga bir nechta tur (data type) bilan ishlaydigan funksiyalar yaratish imkonini beradi.

Oddiy qilib aytganda, agar siz funksiyalar yaratmoqchi bo'lsangiz va ular har xil turdagi ma'lumotlar bilan ishlashini istasangiz, generics sizga bu imkoniyatni beradi.

Generics ishlatmasa nima bo'ladi?

Agar generics bo'lmasa, biz har bir tur uchun alohida kod yozishimiz kerak bo'ladi. Masalan, ikkita sonni solishtiradigan funksiya yozmoqchi bo'lsak, int va float uchun alohida funksiyalar yozishga to'g'ri keladi.

Misol

Ikkita sonni solishtirish funksiyasi:

package main

import "fmt"

func TwoNumbers(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func main() {
    fmt.Println(TwoNumbers(5, 6))
}

Natija:

6

Bu funksiyaga float turidagi qiymat bersak nima sodir bo'ladi? Quyida sinab ko'ramiz.

package main

import "fmt"

func TwoNumbers(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func main() {
    fmt.Println(TwoNumbers(6.8, 6))
}

Natija:

.\main.go:13:25: cannot use 6.8 (untyped float constant) as int value in argument to TwoNumbers (truncated)   

Generics haqida, u nima uchun kerakligi va qanday muamo chiqishi mumkinligi haqida bilib oldik. Endi esa bu muamoga generics bilan yechim izlab ko'ramiz.

Generics qanday yoziladi?

Goda generics type parameters yordamida yoziladi. [] qavs ichida generik parametr nomlanadi.

package main

import "fmt"

func TwoNumbers[T int | float64](a, b T) T {
    if a > b {
        return a
    }
    return b
}

func main() {
    fmt.Println(TwoNumbers(5, 6))
    fmt.Println(TwoNumbers(6.8, 6))
}

Natija:

6
6.8

Yuqoridagi misolda T generic parametr hisoblanadi. O'zgaruvchan tur bo'lib, funksiya chaqirilganda aniq tur bilan almashtiriladi (int yoki float64). Bu yerda T faqat int yoki float64 turidagi qiymatlar bilan ishlashini bildiradi.

Info

Go 1.18 versiyasidan boshlab Generics qo'llab-quvvatlanadi.

Har qanday tur bilan ishlash(any)

Goda any har qanday turdagi qiymatni qabul qilishga imkon beradi. Lekin any bilan ishlashda biz tur tekshirish (type assertion) yoki tur o'zgartirish (type conversion) ni qo'llashimiz kerak, sababi kutilmagan boshqa muamolar keltirib chiqarishi mumkin.

package main

import (
    "fmt"
)

func TwoNumbers(a, b any) any {
    switch a.(type) {
    case int:
        ai := a.(int)
        bi := b.(int)
        if ai > bi {
            return ai
        }
        return bi
        case float64:
            af := a.(float64)
            bf := b.(float64)
            if af > bf {
                return af
            }
            return bf
        default:
            return nil // Noto'g'ri tur bo'lsa, hech narsa qaytarmaydi
    }
}

func main() {
    fmt.Println(TwoNumbers(5, 6))
    fmt.Println(TwoNumbers(6.8, 6.2))
}

Natija:

6
6.8