次期 Go 言語で導入される総称型について予習する(その3)

  1. 次期 Go 言語で導入される(かもしれない)総称型について予習する
  2. 次期 Go 言語で導入される総称型について予習する(その2)
  3. 次期 Go 言語で導入される総称型について予習する(その3) ←イマココ

前回紹介した “Type Parameters - Draft Design” が 2020-09-21 にアップデートされたらしい。 どうやらこれが最終案になりそうだ。

早ければ2021年8月にリリース予定の Go 1.17 でお披露目というスケジュールは変わらない模様。 また総称型(generics)に対応した Playground も最終案の仕様で稼働中である。

前回からの変更点

前回は,たとえば

type ordered interface {
	type int, int8, int16, int32, int64,
		uint, uint8, uint16, uint32, uint64, uintptr,
		float32, float64,
		string
}

func Max(type T ordered)(x, y T) T {
    if x < y {
        return y
    }
    return x
}

のような記述だったが,今回は型パラメータ(type parameter)の記述がちょっと変わったようで

type ordered interface {
	type int, int8, int16, int32, int64,
		uint, uint8, uint16, uint32, uint64, uintptr,
		float32, float64,
		string
}

func Max[T ordered](x, y T) T {
	if x < y {
		return y
	}
	return x
}

と角括弧 [...] で囲まれている。 どうしても山括弧 <...> はイヤみたい(笑)

type キーワードは無用となった。

組込み済みの制約

組込み済みの interface 型として error が定義されているように,組込み済みの制約(constraint)として anycomparable が追加されるようだ。

any はあらゆる型を包摂する。 むしろ「制約がない」ことを示す制約というべきか。 強いて書くなら

type any interface{}

といったところだろうか。 たとえば

// Print prints the elements of any slice.
// Print has a type parameter T and has a single (non-type)
// parameter s which is a slice of that type parameter.
func Print[T any](s []T) {
    for _, v := range s {
		fmt.Println(v)
	}
}
via Type Parameters - Draft Design

みたいな感じに使える。 どうやら型パラメータの指定で制約を省略することはできないようなので,制約がない場合は any を付けることになりそうだ。

comparable は演算子 == および !== が使える型を示す制約だ。 これを使って

package main

import "fmt"

func Contains[T comparable](col []T, item T) bool {
	for _, e := range col {
		if e == item {
			return true
		}
	}
	return false
}

func main() {
	fmt.Println(Contains([]string{"coffee", "tea"}, "coffee")) //true
	fmt.Println(Contains([]int{1, 2, 3}, 11))                  //false
	fmt.Println(Contains([]int{1, 2, 3}, 1))                   //true
}
via Go Generics draft design Final

のように書ける。

anycomparable も制約としてのみ使用可能で,通常の inteface 型としては使えないようだ。

なお, Go の総称型について詳しくは以下の「本」がオススメである。 色々な事例が載っているのでかなり参考になる。

この本を買うために Zenn のアカウントを取ってもいいかも(クレカが通ればだけど)。

Go は Nearly Java になるか

上述の「本」に

その慎重な Go が今、Generics を取り入れ、Better C から Nearly Java へと変わろうとしています。Java がそうであった様に、Go は Generics の導入により多くのアルゴリズムが汎用的に実装され便利になっていくでしょう
Go 言語にやってくる Generics は我々に何をもたらすのかより

とある。 標準の sort パッケージのように型ごとに似たようなコードをゴリゴリ書くのではなく,汎化されたアルゴリズムに集約されていく期待感はあるが,それが Nearly Java になるかについては懐疑的である。

Go 言語の特徴のひとつは「汎化」の実装として Java や Rust のような公称型の部分型付け(nominal subtyping)ではなく構造型の部分型付け(structural subtyping)を採用していることにある。 当然ながらこれは総称型を使ったアルゴリズムの実装にも大きな影響を与える筈である。

私は Go が総称型を得ることで更に独自に発展することを期待している。

ブックマーク

参考図書

photo
プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
Alan A.A. Donovan (著), Brian W. Kernighan (著), 柴田 芳樹 (翻訳)
丸善出版 2016-06-20
単行本(ソフトカバー)
4621300253 (ASIN), 9784621300251 (EAN), 4621300253 (ISBN), 9784621300251 (ISBN)
評価     

著者のひとりは(あの「バイブル」とも呼ばれる)通称 “K&R” の K のほうである。この本は Go 言語の教科書と言ってもいいだろう。

reviewed by Spiegel on 2016-07-13 (powered by PA-APIv5)