Чӣ тавр ҷамъбасти намудҳо ва чӣ гуна онро дар 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 аз навъҳои optional type Option struct { Value *int // Нулӣ агар арзиш вуҷуд дошта бошад } // None арзиши нулӣ эҷод мекунад func None() Option { return Option{} } // Some бо арзиш эҷод мекунад 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 мебошад. Ин кафолат медиҳад, ки танҳо яке аз вариантҳо ҳузур дорад ва бехатарии навъҳоро дар вақти кор таъмин мекунад.