Co je to součet typů a jak jej implementovat v Go?
sobes.tech AI
Odpověď od AI
Součet typů (nebo označené sjednocení, disjunktní sjednocení) je datový typ, který může nabývat hodnoty jedné z několika předdefinovaných možností. Na rozdíl od typu produktu (struktur), kde hodnota obsahuje všechna pole současně, součet typů obsahuje pouze jednu z možných hodnot.
V Go není přímá podpora součtu typů jako v jazycích jako Haskell nebo Rust (enum). Součet typů lze napodobit několika způsoby:
-
Rozhraní a tvrzení typu (Type Assertion):
Vytvořte rozhraní, které budou implementovat všechny možné varianty. Hodnota součtu typů bude představovat toto rozhraní, a pro určení konkrétní varianty se používá tvrzení typu nebo
type switch.package main import "fmt" // Shape - rozhraní reprezentující součet typů type Shape interface { Area() float64 } // Circle - jedna z variant type Circle struct { Radius float64 } func (c Circle) Area() float64 { return 3.14 * c.Radius * c.Radius } // Rectangle - jiná varianta 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 { // Použití switch na typ pro určení varianty switch v := s.(type) { case Circle: fmt.Printf("Kruh s poloměrem %.2f, plocha: %.2f\n", v.Radius, v.Area()) case Rectangle: fmt.Printf("Obdélník s rozměry %.2f x %.2f, plocha: %.2f\n", v.Width, v.Height, v.Area()) default: fmt.Println("Neznámý tvar") } } } -
Struktury s booleanovými vlajkami (zřídka používané):
Struktura obsahuje pole pro všechny možné varianty a booleanové vlajky, které ukazují, která varianta je aktivní. Je to nebezpečné a složité na údržbu.
package main import "fmt" type Result struct { Value int // Pole pro úspěšný výsledek Err error // Pole pro chybu IsValue bool // Vlajka, která ukazuje, zda je aktivní Value IsErr bool // Vlajka, která ukazuje, zda je aktivní Err } func Process(input int) Result { if input > 0 { return Result{Value: input * 2, IsValue: true} } return Result{Err: fmt.Errorf("záporné číslo: %d", input), IsErr: true} } func main() { res1 := Process(10) if res1.IsValue { fmt.Printf("Výsledek: %d\n", res1.Value) } else if res1.IsErr { fmt.Printf("Chyba: %v\n", res1.Err) } res2 := Process(-5) if res2.IsValue { fmt.Printf("Výsledek: %d\n", res2.Value) } else if res2.IsErr { fmt.Printf("Chyba: %v\n", res2.Err) } } -
Struktury s nulovou hodnotou pro neaktivní pole (často používané pro Optional/Result):
Struktura obsahuje pole pro všechny možné varianty, ale pouze jedno z nich bude nenulové. Funguje dobře pro ukazatele nebo typy s jasnou "nulovou" hodnotou.
package main import "fmt" // Option - emulace Some/None z volitelného typu type Option struct { Value *int // Nenulové, pokud je hodnota přítomna } // None vytváří nulovou hodnotu Option func None() Option { return Option{} } // Some vytváří Option s hodnotou func Some(val int) Option { return Option{Value: &val} } func main() { opt1 := Some(10) if opt1.Value != nil { fmt.Printf("Hodnota: %d\n", *opt1.Value) } else { fmt.Println("Žádná hodnota") } opt2 := None() if opt2.Value != nil { fmt.Printf("Hodnota: %d\n", *opt2.Value) } else { fmt.Println("Žádná hodnota") } }
Nejidiomatičtější a nejbezpečnější způsob emulace součtu typů v Go je použití rozhraní a type switch. To zaručuje, že je přítomen pouze jeden z variant a poskytuje typovou bezpečnost při práci s ním.