Типтердин жыйындысы эмне жана аны Goда кантип ишке ашыруу керек?
sobes.tech AI
AIден жооп
Типтердин суммасы (же белгиленген бирикмеси, дизъюнкттүү бирикмеси) — бул бир нече алдын ала аныкталган варианттардын бирине кабыл алууга мүмкүнчүлүк берген маалымат түрү. Структуралардын көбөйтүүсүнөн айырмаланып (структуралар), анда баа бирден көп өрөөндөрдү камтыйт, типтердин суммасы тек гана бир мүмкүн болгон маанини камтыйт.
Go тилинде Haskell же Rust (enum) сыяктуу түрлөрдүн суммасын түздөн-түз колдоо жок. Бул суммаларды бир нече жол менен имитациялоо мүмкүн:
-
Интерфейстер жана типти ырастоо (Type Assertion):
Бардык мүмкүн болгон варианттарды ишке ашырган интерфейсти түзүңүз. Суммалык түрдүн мааниси ушул интерфейс болуп саналат, жана конкреттүү вариантты аныктоо үчүн типти ырастоо же
type switchколдонулат.package main import "fmt" // Shape — суммалык түрдү көрсөтүүчү интерфейс type Shape interface { Area() float64 } // Circle — бир вариант type Circle struct { Radius float64 } func (c Circle) Area() float64 { return 3.14 * c.Radius * c.Radius } // Rectangle — башка вариант 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 { // Типти өзгөртүү үчүн `type switch` колдонуу switch v := s.(type) { case Circle: fmt.Printf("дөңгөлөк радиусу %.2f, аянты: %.2f\n", v.Radius, v.Area()) case Rectangle: fmt.Printf("тегерек өлчөмдөрү %.2f x %.2f, аянты: %.2f\n", v.Width, v.Height, v.Area()) default: fmt.Println("Белгисиз форма") } } } -
Булгаары белгилер менен структуралар (аз колдонулат):
Структура бардык мүмкүн болгон варианттарды камтыйт жана активдүү болгон вариант үчүн булгаары белгилер бар. Бул коопсуз эмес жана кармоо кыйын.
package main import "fmt" type Result struct { Value int // ийгиликтүү натыйжа үчүн өрөөн Err error // ката үчүн өрөөн IsValue bool // флаг, Value активдүү экенин көрсөтүү IsErr bool // флаг, Err активдүү экенин көрсөтүү } func Process(input int) Result { if input > 0 { return Result{Value: input * 2, IsValue: true} } return Result{Err: fmt.Errorf("терс сан: %d", input), IsErr: true} } func main() { res1 := Process(10) if res1.IsValue { fmt.Printf("Натыйжа: %d\n", res1.Value) } else if res1.IsErr { fmt.Printf("Ката: %v\n", res1.Err) } res2 := Process(-5) if res2.IsValue { fmt.Printf("Натыйжа: %d\n", res2.Value) } else if res2.IsErr { fmt.Printf("Ката: %v\n", res2.Err) } } -
Нөлдөнүүчү мааниге ээ структуралар (көбүнчө Optional/Result үчүн колдонулат):
Бардык мүмкүн болгон варианттар үчүн өрөөндөрдү камтыйт, бирок алардын бир гана бири нөл эмес мааниге ээ болот. Бул көрсөткүчтөр же так "нөл" мааниге ээ түрлөр үчүн жакшы иштейт.
package main import "fmt" // Option — Some/None эмуляциясы type Option struct { Value *int // Нөл эмес, эгер мааниси болсо } // None — нөл маанилүү Option түзөт func None() Option { return Option{} } // Some — мааниси бар Option түзөт func Some(val int) Option { return Option{Value: &val} } func main() { opt1 := Some(10) if opt1.Value != nil { fmt.Printf("Мән бар: %d\n", *opt1.Value) } else { fmt.Println("Мән жок") } opt2 := None() if opt2.Value != nil { fmt.Printf("Мән бар: %d\n", *opt2.Value) } else { fmt.Println("Мән жок") } }
Go тилинде суммалык түрлөрдү имитациялоонун эң идиоматтуу жана коопсуз жолу — интерфейстер жана type switch колдонуу. Бул ыкма, бир гана варианттын болушун камсыздайт жана иштөөдө түр коопсуздугун камсыздайт.