Növlərin cəmi nədir və onu Go-da necə həyata keçirmək olar?
sobes.tech Süni İntellekt
AI-dan cavab
Növ növlərinin cəmisi (və ya etiketli birləşmə, disjunkt birləşmə) — bu, bir neçə əvvəlcədən təyin olunmuş variantlardan birini qəbul edə bilən məlumat növüdür. Növ məhsulundan fərqli olaraq (struktur), burada dəyər bütün sahələri eyni zamanda ehtiva etmir, yalnız bir variantı ehtiva edir.
Go-da, Haskell və ya Rust (enum) kimi dillərdə olduğu kimi, növ cəmisi üçün birbaşa dəstək yoxdur. Növ cəmisi müxtəlif üsullarla emulyasiya oluna bilər:
-
İnterfeyslər və növ təsdiqi (Type Assertion):
Bütün mümkün variantları həyata keçirən bir interfeis yaradın. Növ cəmisi dəyəri bu interfeisi təmsil edəcək və konkret variantı müəyyən etmək üçün növ təsdiqi və ya
type switchistifadə olunur.package main import "fmt" // Shape - növ cəmisini təmsil edən interfeis type Shape interface { Area() float64 } // Circle - variantlardan biri type Circle struct { Radius float64 } func (c Circle) Area() float64 { return 3.14 * c.Radius * c.Radius } // Rectangle - digər variant type Rectangle struct { Width, Height float64 } func (r Rectangle) Area() float64 { return r.Width * r.Height } func main() { shapes := []Shape{Circle{Radius: 5}, Rectangle{Width: 3, Height: 4}} for _, s := range shapes { // Növ switch istifadə edərək variantı müəyyən etmək switch v := s.(type) { case Circle: fmt.Printf("Dairə radius %.2f, sahə: %.2f\n", v.Radius, v.Area()) case Rectangle: fmt.Printf("Dikdörtgen ölçüləri %.2f x %.2f, sahə: %.2f\n", v.Width, v.Height, v.Area()) default: fmt.Println("Naməlum forma") } } } -
Boolean bayraqları olan strukturlar (nadir istifadə olunur):
Struktur bütün mümkün variantlar üçün sahələr ehtiva edir və hansı variantın aktiv olduğunu göstərmək üçün boolean bayraqları var. Bu, təhlükəsiz deyil və dəstəklənməsi çətindir.
package main import "fmt" type Result struct { Value int // Uğurlu nəticə üçün sahə Err error // Xəta üçün sahə IsValue bool // Value aktiv olub-olmadığını göstərir IsErr bool // Err aktiv olub-olmadığını göstərir } func Process(input int) Result { if input > 0 { return Result{Value: input * 2, IsValue: true} } return Result{Err: fmt.Errorf("mənfi ədəd: %d", input), IsErr: true} } func main() { res1 := Process(10) if res1.IsValue { fmt.Printf("Nəticə: %d\n", res1.Value) } else if res1.IsErr { fmt.Printf("Xəta: %v\n", res1.Err) } res2 := Process(-5) if res2.IsValue { fmt.Printf("Nəticə: %d\n", res2.Value) } else if res2.IsErr { fmt.Printf("Xəta: %v\n", res2.Err) } } -
Null dəyərli strukturlar (adətən Optional/Result üçün istifadə olunur):
Struktur bütün mümkün variantlar üçün sahələr ehtiva edir, lakin yalnız biri qeyri-sıfır olacaq. Pointerlər və ya aydın "sıfır" dəyəri olan tiplər üçün yaxşı işləyir.
package main import "fmt" // Option - optional tipindən Some/None emulyasiyası type Option struct { Value *int // Dəyər varsa, null deyil } // None null Option dəyəri yaradır func None() Option { return Option{} } // Some dəyər ilə Option yaradır func Some(val int) Option { return Option{Value: &val} } func main() { opt1 := Some(10) if opt1.Value != nil { fmt.Printf("Dəyər: %d\n", *opt1.Value) } else { fmt.Println("Dəyər yoxdur") } opt2 := None() if opt2.Value != nil { fmt.Printf("Dəyər: %d\n", *opt2.Value) } else { fmt.Println("Dəyər yoxdur") } }
Go-da növ cəmisi emulyasiyasının ən idiyomatik və təhlükəsiz yolu interfeyslər və type switch istifadə etməkdir. Bu, yalnız bir variantın mövcud olmasını təmin edir və onunla işləyərkən növ təhlükəsizliyi təmin edir.