Sobes.tech
Senior

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:

  1. İ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 switch istifadə 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")
    		}
    	}
    }
    
  2. 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)
    	}
    }
    
  3. 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.