Kas yra tipų suma ir kaip ją įgyvendinti Go kalboje?
sobes.tech AI
Atsakymas iš AI
Tipų suma (arba pažymėtas unijos, disjunktyvinės unijos) — tai duomenų tipas, kuris gali priimti vieną iš kelių iš anksto apibrėžtų variantų. Skirtingai nuo tipų produktų (struktūrų), kuriose reikšmė apima visus laukus vienu metu, tipų suma apima tik vieną iš galimų reikšmių.
Go kalboje nėra tiesioginės tipų sumų palaikymo kaip Haskell ar Rust (enum). Tipų sumas galima imituoti keliais būdais:
-
Sąsajos ir tipo patvirtinimas (Type Assertion):
Sukurkite sąsają, kuri įgyvendins visas galimas variacijas. Tipų suma reikšmė bus šios sąsajos įgyvendinimas, o konkrečios variacijos nustatymui naudojamas tipo patvirtinimas arba
type switch.package main import "fmt" // Shape - sąsaja, atstovaujanti tipų sumą type Shape interface { Area() float64 } // Circle - viena iš variacijų type Circle struct { Radius float64 } func (c Circle) Area() float64 { return 3.14 * c.Radius * c.Radius } // Rectangle - kita variacija 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 { // Tipų switch naudojimas variacijai nustatyti switch v := s.(type) { case Circle: fmt.Printf("Apskritimas su spinduliu %.2f, plotas: %.2f\n", v.Radius, v.Area()) case Rectangle: fmt.Printf("Stačiakampis su matmenimis %.2f x %.2f, plotas: %.2f\n", v.Width, v.Height, v.Area()) default: fmt.Println("Nežinoma forma") } } } -
Struktūros su boolean ženklais (retai naudojama):
Struktūra turi visus galimus variantus ir boolean ženklais nurodo, kuris variantas aktyvus. Tai nesaugus ir sunku palaikyti.
package main import "fmt" type Result struct { Value int // Sėkmingo rezultato laukas Err error // Klaidos laukas IsValue bool // Žymeklis, nurodantis, ar aktyvus Value IsErr bool // Žymeklis, nurodantis, ar aktyvus Err } func Process(input int) Result { if input > 0 { return Result{Value: input * 2, IsValue: true} } return Result{Err: fmt.Errorf("neigiamas skaičius: %d", input), IsErr: true} } func main() { res1 := Process(10) if res1.IsValue { fmt.Printf("Rezultatas: %d\n", res1.Value) } else if res1.IsErr { fmt.Printf("Klaida: %v\n", res1.Err) } res2 := Process(-5) if res2.IsValue { fmt.Printf("Rezultatas: %d\n", res2.Value) } else if res2.IsErr { fmt.Printf("Klaida: %v\n", res2.Err) } } -
Struktūros su nuline reikšme neaktyviems laukams (dažnai naudojama Optional/Result):
Struktūra turi visus galimus laukus, bet tik vienas iš jų bus nulinės reikšmės. Gerai veikia su nuorodomis arba tipais, turinčiais aiškią "nulines" reikšmę.
package main import "fmt" // Option - emuliacija Some/None iš pasirinktinio tipo type Option struct { Value *int // Nulinė, jei yra reikšmė } // None sukuria nulinės reikšmės Option func None() Option { return Option{} } // Some sukuria Option su reikšme func Some(val int) Option { return Option{Value: &val} } func main() { opt1 := Some(10) if opt1.Value != nil { fmt.Printf("Reikšmė yra: %d\n", *opt1.Value) } else { fmt.Println("Reikšmė nėra") } opt2 := None() if opt2.Value != nil { fmt.Printf("Reikšmė yra: %d\n", *opt2.Value) } else { fmt.Println("Reikšmė nėra") } }
Geriausias ir saugiausias būdas imituoti tipų sumas Go kalboje — naudoti sąsajas ir type switch. Tai leidžia garantuoti, kad tik vienas variantas yra aktyvus, ir užtikrina tipų saugumą naudojant.