Türlerin toplamı nedir ve Go'da nasıl uygulanır?
sobes.tech yapay zeka
AI'dan gelen yanıt
Türlerin toplamı (veya etiketli birleşim, ayrık birleşim) birkaç önceden tanımlanmış değeri alabilen bir veri türüdür. Haskell veya Rust gibi dillerdeki (enum) gibi doğrudan desteklenmediği için, Go'da tür toplamı birkaç şekilde taklit edilebilir:
-
Arayüzler ve Tür İddiası (Type Assertion):
Tüm olası varyantları uygulayan bir arayüz oluşturun. Tür toplamının değeri bu arayüz olacak ve belirli varyantı belirlemek için tür iddiası veya
type switchkullanılır.package main import "fmt" // Shape - toplam türü temsil eden arayüz type Shape interface { Area() float64 } // Circle - bir varyant type Circle struct { Radius float64 } func (c Circle) Area() float64 { return 3.14 * c.Radius * c.Radius } // Rectangle - başka bir varyant 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 { // Tür switch kullanarak varyantı belirleme switch v := s.(type) { case Circle: fmt.Printf("Daire yarıçap %.2f, alan: %.2f\n", v.Radius, v.Area()) case Rectangle: fmt.Printf("Dikdörtgen ölçüleri %.2f x %.2f, alan: %.2f\n", v.Width, v.Height, v.Area()) default: fmt.Println("Bilinmeyen şekil") } } } -
Boolean bayraklar içeren yapılar (nadiren kullanılır):
Yapı, tüm olası varyantlar için alanlar içerir ve hangi varyantın aktif olduğunu belirten boolean bayraklar içerir. Güvenli değil ve bakım zordur.
package main import "fmt" type Result struct { Value int // Başarılı sonuç için alan Err error // Hata için alan IsValue bool // Aktif olup olmadığını gösteren bayrak IsErr bool // Aktif olup olmadığını gösteren bayrak } func Process(input int) Result { if input > 0 { return Result{Value: input * 2, IsValue: true} } return Result{Err: fmt.Errorf("negatif sayı: %d", input), IsErr: true} } func main() { res1 := Process(10) if res1.IsValue { fmt.Printf("Sonuç: %d\n", res1.Value) } else if res1.IsErr { fmt.Printf("Hata: %v\n", res1.Err) } res2 := Process(-5) if res2.IsValue { fmt.Printf("Sonuç: %d\n", res2.Value) } else if res2.IsErr { fmt.Printf("Hata: %v\n", res2.Err) } } -
Aktif olmayan alanlar için null değeri içeren yapılar (sıkça Optional/Result için kullanılır):
Yapı, tüm olası varyantlar için alanlar içerir, ancak yalnızca biri null olmayan değere sahip olur. İşlevseldir ve göstergeçler veya net "null" değeri olan türlerle iyi çalışır.
package main import "fmt" // Option - Opsiyonel türden Some/None emülasyonu type Option struct { Value *int // Değer varsa null değil } // None, null Option oluşturur func None() Option { return Option{} } // Some, bir değerle Option oluşturur func Some(val int) Option { return Option{Value: &val} } func main() { opt1 := Some(10) if opt1.Value != nil { fmt.Printf("Değer: %d\n", *opt1.Value) } else { fmt.Println("Değer yok") } opt2 := None() if opt2.Value != nil { fmt.Printf("Değer: %d\n", *opt2.Value) } else { fmt.Println("Değer yok") } }
Go'da tür toplamını taklit etmenin en idiomatik ve güvenli yolu, arayüzler ve type switch kullanmaktır. Bu, yalnızca bir varyantın mevcut olmasını sağlar ve onunla çalışırken tür güvenliği sağlar.