Čo je súčet typov a ako ho implementovať v Go?
sobes.tech AI
Odpoveď od AI
Súčet typov (alebo označené zjednotenie, disjunktné zjednotenie) je dátový typ, ktorý môže nadobudnúť hodnotu jednej z viacerých preddefinovaných možností. Na rozdiel od produktu typov (štruktúr), kde hodnota obsahuje všetky polia súčasne, súčet typov obsahuje iba jednu z možných hodnôt.
V Go nie je priama podpora súčtu typov ako v jazykoch ako Haskell alebo Rust (enum). Súčet typov možno emulovať viacerými spôsobmi:
-
Rozhrania a tvrdenie o type (Type Assertion):
Vytvorte rozhranie, ktoré budú implementovať všetky možné varianty. Hodnota súčtu typov bude predstavovať toto rozhranie, a na určenie konkrétnej varianty sa používa tvrdenie o type alebo
type switch.package main import "fmt" // Shape - rozhranie reprezentujúce súčet typov type Shape interface { Area() float64 } // Circle - jedna z možností type Circle struct { Radius float64 } func (c Circle) Area() float64 { return 3.14 * c.Radius * c.Radius } // Rectangle - iná možnosť 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žitie switch na type na určenie možnosti switch v := s.(type) { case Circle: fmt.Printf("Kruh s polomerom %.2f, plocha: %.2f\n", v.Radius, v.Area()) case Rectangle: fmt.Printf("Obdĺžnik s rozmermi %.2f x %.2f, plocha: %.2f\n", v.Width, v.Height, v.Area()) default: fmt.Println("Neznámy tvar") } } } -
Štruktúry s booleanovými vlajkami (zriedka používané):
Štruktúra obsahuje polia pre všetky možné možnosti a booleanové vlajky na označenie, ktorá možnosť je aktívna. Je to nebezpečné a ťažké na údržbu.
package main import "fmt" type Result struct { Value int // Pole pre úspešný výsledok Err error // Pole pre chybu IsValue bool // Vlajka, ktorá ukazuje, či je aktívne Value IsErr bool // Vlajka, ktorá ukazuje, či je aktívne 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ýsledok: %d\n", res1.Value) } else if res1.IsErr { fmt.Printf("Chyba: %v\n", res1.Err) } res2 := Process(-5) if res2.IsValue { fmt.Printf("Výsledok: %d\n", res2.Value) } else if res2.IsErr { fmt.Printf("Chyba: %v\n", res2.Err) } } -
Štruktúry s nulovou hodnotou pre neaktívne polia (často používané pre Optional/Result):
Štruktúra obsahuje polia pre všetky možné možnosti, ale iba jedno z nich bude nenulové. Funguje dobre pre ukazovatele alebo typy s jasnou "nulovou" hodnotou.
package main import "fmt" // Option - emulácia Some/None z voliteľného typu type Option struct { Value *int // Nenulové, ak je hodnota prítomná } // None vytvára nulovú hodnotu Option func None() Option { return Option{} } // Some vytvára Option so 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("Žiadna hodnota") } opt2 := None() if opt2.Value != nil { fmt.Printf("Hodnota: %d\n", *opt2.Value) } else { fmt.Println("Žiadna hodnota") } }
Najidiomatičnejší a najbezpečnejší spôsob emulácie súčtu typov v Go je použitie rozhraní a type switch. To zabezpečuje, že je prítomná iba jedna z možností a poskytuje typovú bezpečnosť pri práci s ňou.