https://zenn.dev/nobishii/articles/type_param_intro
Go1.18のリリースは2022年3月の予定になっており、ジェネリクスを含む言語仕様書はかなりの頻度で加筆修正されています。 この記事ではできるだけ最新の仕様と用語法にもとづいてジェネリクスの言語仕様について解説していきます。
シリーズ
実用上は最初の「基本原則とシンプルな例」というセクションの内容で十分なことが多いと思います。とりあえずここだけ読むのをおすすめします。
Goジェネリクスの基本原則とシンプルな例を説明します。シンプルな例と言っても、ユースケースの大半はこれで尽くされると思いますので、この節だけ読んで終わりにするのもおすすめです。
Goのジェネリクスの基本事項についてはType Parameters Proposalの冒頭に挙げられています。このうち特に重要なのは次の2つです。この2つを覚えればGoのジェネリクスを十分に使うことができると思います。
f[T Stringer]
まず「型パラメータを持つ関数」の具体例を見てみましょう。
func main() {
fmt.Println(f([]MyInt{1, 2, 3, 4}))
// Output:
// [1 2 3 4]
}
// fは型パラメータを持つ関数
// Tは型パラメータ
// インタフェースStringerは、Tに対する型制約として使われている
func f[T Stringer](xs []T) []string {
var result []string
for _, x := range xs {
// xは型制約StringerによりString()メソッドが使える
result = append(result, x.String())
}
return result
}
type Stringer interface {
String() string
}
type MyInt int
// MyIntはStringerを実装する
func (i MyInt) String() string {
return strconv.Itoa(int(i))
}
関数f
の宣言時にf[T Stringer]
という四角カッコの文法要素がついていますね。これが型パラメータと一緒に導入される新しい文法です。この意味は、
f
において型パラメータT
を宣言するT
型はインタフェースStringer
を実装する型である、という型制約を設ける