はじめに
GoもUnion型が使えるといいなと思って、調べたのですが残念ながらないみたいですね!
ただ、代用方法がいくつか提示されていたので、勉強がてら紹介したいと思います。
タグ付き構造体を使う
main.go
package main
import "fmt"
// ユニオン型を表現するタグ付き構造体
type ItemResult struct {
Type string
Value interface{}
}
// 処理を行う関数
func ProcessItem(item ItemResult) {
switch item.Type {
case "int":
fmt.Println("Integer:", item.Value.(int))
case "string":
fmt.Println("String:", item.Value.(string))
case "float64":
fmt.Println("Float64:", item.Value.(float64))
default:
fmt.Println("Unknown type")
}
}
func main() {
ProcessItem(ItemResult{Type: "int", Value: 100}) // 出力: Integer: 100
ProcessItem(ItemResult{Type: "string", Value: "Hello"}) // 出力: String: Hello
ProcessItem(ItemResult{Type: "float64", Value: 99.9}) // 出力: Float64: 99.9
}
Type string
でどの型かを持たせ、Validationチェックを実施制御
インターフェースを使う方法
main.go
package main
import "fmt"
// インターフェースでユニオン型を表現
type ItemResult interface{}
// 型スイッチで処理を分岐
func ProcessItem(item ItemResult) {
switch v := item.(type) {
case int:
fmt.Println("Integer:", v)
case string:
fmt.Println("String:", v)
case float64:
fmt.Println("Float64:", v)
default:
fmt.Println("Unknown type")
}
}
func main() {
ProcessItem(100) // 出力: Integer: 100
ProcessItem("Hello") // 出力: String: Hello
ProcessItem(99.9) // 出力: Float64: 99.9
ProcessItem(true) // 出力: Unknown type
}
型制約(Generics)を使う
package main
import "fmt"
// ユニオン型を表現する型制約
type ItemType interface {
int | string | float64
}
// ジェネリック構造体
type Container[T ItemType] struct {
Value T
}
// 値を表示する関数
func Display[T ItemType](c Container[T]) {
fmt.Printf("Type: %T, Value: %v\n", c.Value, c.Value)
}
func main() {
// 許可された型を使用
intContainer := Container[int]{Value: 100}
stringContainer := Container[string]{Value: "Hello"}
floatContainer := Container[float64]{Value: 99.9}
// 値を表示
Display(intContainer) // 出力: Type: int, Value: 100
Display(stringContainer) // 出力: Type: string, Value: Hello
Display(floatContainer) // 出力: Type: float64, Value: 99.9
// 許可されない型はエラー
// boolContainer := Container[bool]{Value: true} // コンパイルエラー
}
Genericsはv1.18以降で導入されています。