https://zenn.dev/nobishii/articles/type_param_intro

Go1.18のリリースは2022年3月の予定になっており、ジェネリクスを含む言語仕様書はかなりの頻度で加筆修正されています。 この記事ではできるだけ最新の仕様と用語法にもとづいてジェネリクスの言語仕様について解説していきます。

シリーズ

Untitled

章目次

実用上は最初の「基本原則とシンプルな例」というセクションの内容で十分なことが多いと思います。とりあえずここだけ読むのをおすすめします。

Untitled

基本原則とシンプルな例

Goジェネリクスの基本原則とシンプルな例を説明します。シンプルな例と言っても、ユースケースの大半はこれで尽くされると思いますので、この節だけ読んで終わりにするのもおすすめです。

Goのジェネリクスの基本原則

Goのジェネリクスの基本事項についてはType Parameters Proposalの冒頭に挙げられています。このうち特に重要なのは次の2つです。この2つを覚えればGoのジェネリクスを十分に使うことができると思います。

具体例1: 型パラメータを持つ関数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]という四角カッコの文法要素がついていますね。これが型パラメータと一緒に導入される新しい文法です。この意味は、