Sobes.tech
Senior

Типтердин жыйындысы эмне жана аны Goда кантип ишке ашыруу керек?

sobes.tech AI

AIден жооп

Типтердин суммасы (же белгиленген бирикмеси, дизъюнкттүү бирикмеси) — бул бир нече алдын ала аныкталган варианттардын бирине кабыл алууга мүмкүнчүлүк берген маалымат түрү. Структуралардын көбөйтүүсүнөн айырмаланып (структуралар), анда баа бирден көп өрөөндөрдү камтыйт, типтердин суммасы тек гана бир мүмкүн болгон маанини камтыйт.

Go тилинде Haskell же Rust (enum) сыяктуу түрлөрдүн суммасын түздөн-түз колдоо жок. Бул суммаларды бир нече жол менен имитациялоо мүмкүн:

  1. Интерфейстер жана типти ырастоо (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("Белгисиз форма")
    		}
    	}
    }
    
  2. Булгаары белгилер менен структуралар (аз колдонулат):

    Структура бардык мүмкүн болгон варианттарды камтыйт жана активдүү болгон вариант үчүн булгаары белгилер бар. Бул коопсуз эмес жана кармоо кыйын.

    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)
    	}
    }
    
  3. Нөлдөнүүчү мааниге ээ структуралар (көбүнчө 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 колдонуу. Бул ыкма, бир гана варианттын болушун камсыздайт жана иштөөдө түр коопсуздугун камсыздайт.