Goのジェネリクス
Goには、ジェネリクスという概念があります。関数か構造体を定義する際に、一部の型を変数として扱い、コードの再利用性の向上させます。
// generic function
// ok
func UseOrElse[T any](cond bool, first, second T) T {
if cond {
return first
}
return second
}
// generic struct
// ok
type NullValue[T any] struct {
Value T
Valid bool
}
が、ジェネリックメソッドはまだ未対応です。
type Helper struct {}
// generic method
// error!
func (h Helper) UseOrElse[T any](cond bool, first, second T) T {
if cond {
return first
}
return second
}
こう書くと、[T any]
の部分に波線が出て、IDEからMethod cannot have type parameters
(メソッドには型変数を指定できません)と表示されます。
回避策
ラッパー構造体を作り、型変数を構造体のところに移す。
便宜上、元の構造体を本構造体と呼びます。
本構造体とラッパー構造体を同じパッケージに定義することによって、本構造体のプライベートフィールドもラッパー構造体からアクセス可能です。
// ok
type Helper struct {
PublicFlag string
privateFlag string
}
type Wrapper[T any] struct {
h Helper
}
func (c Wrapper[T]) UseOrElse(cond bool, first, second T) T {
fmt.Println(c.h.PublicFlag)
fmt.Printf(c.h.privateFlag) // ok!
if cond {
return first
}
return second
}
呼び出す方法:
var h Helper
_ = Wrapper[int]{h}.UseOrElse(false, 1, 2)
_ = Wrapper[string]{h}.UseOrElse(true, "hello", "world")