GoのGenerics関連のAcceptされたProposalを全部紹介する会 発表資料
目次
初めに読むべきもの
- go: don't change the libraries in 1.18
各Proposalの紹介
- type parameters (軽めに)
- type sets (軽めに)
- constraints package
- slices package
- go/ast changes for generics
- maps package
- sort: generic functions
- allow 'any' for 'interface{}' in non-constraint contexts
- type parameters on aliases
- allow eliding interface{ } in constraint literals
- go/types changes for generics
その他
Discussion
資料集
宣伝
- GoConの登壇告知
- #gospecreading のイベント告知
初めに読むべきもの
go: don't change the libraries in 1.18 (#48918)
(注) この内容は決定事項ではなく、まだ議論中です
Rob Pikeによる提案で、Go 1.18では標準ライブラリを更新するのをやめたい、と言う内容。
Go 1.18は、Go言語が作られて以来最も大きな変更になるので、1度に全てを行うと判断を誤る可能性があるのでは、といった文脈で提案が出ている。
標準ライブラリに対する変更を行うと、後方互換性を保つ責任も発生する。
そのため、直接標準ライブラリを更新するのではなく、まずは、 golang.org/x/exp
に入れて様子を見たい、と言うことが提案されている。
exp packageは、標準化されていないpackageが置かれている golang.org/x
よりも更に試験的なもの、と言う扱い。
標準ライブラリにGenericsに関するpackageが入らなかったとしても、expから使えるので利便性は損なわないはず、と言う主張。
この提案内容が通ったら、これから説明する標準ライブラリに関するProposalの内容は、Acceptされているにも関わらずGo 1.18では標準ライブラリに入らない可能性があります。
(個人的には、このIssueの内容には賛成です)
各Proposalの紹介
type parameters: accepted (2021/2/11)
Goでジェネリックなプログラミングを行えるようにするために、型や関数が type parameter を受け付けることを出来るようにする提案です。
型パラメータが受け付ける型に対しての constraints の導入や、型推論のルールについてもこの提案に含まれています。
tenntennさんの資料 によくまとまっています
Proposal内[1]のコード例
// Stringer is a type constraint that requires the type argument to have
// a String method and permits the generic function to call String.
// The String method should return a string representation of the value.
type Stringer interface {
String() string
}
// Stringify calls the String method on each element of s,
// and returns the results.
func Stringify[T Stringer](s []T) (ret []string) {
for _, v := range s {
ret = append(ret, v.String())
}
return ret
}
type sets: accepted (2021/7/22)
Nobishiiさんの資料 によくまとまっています
type parameters proposalがacceptされた時点で含まれていた、constraintsにおける type list を置き換える提案です。
type listのわかりにくさを解消し、より一般的な解決法を提案したもので、2021年7月にacceptされました。
コード例
type PredeclaredSignedInteger interface {
int | int8 | int16 | int32 | int64
}
type SignedInteger interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
constraints package: accepted (2021/8/19)
頻繁に使われるであろう制約の定義をまとめたpackageです。
過去の記事で詳しく紹介しています。
このProposalはAcceptされましたが、 #47916 で一部定義の置き換えが行われそうです。
slices package: accepted (2021/8/12)
sliceをジェネリックに操作したい時に使うpackageです。
過去の記事で詳しく紹介しています。
go/ast changes for generics: accepted (2021/9/16)
静的解析関連のpackage、go/ast に対する変更。
(DQNEOさんと読みます)
maps package: accepted (2021/9/23)
mapをジェネリックに操作したい時に使うpackageです。
過去の記事で詳しく紹介しています。
sort: generic functions: accepted (2021/9/23)
sliceをジェネリックにソートしたい時に使う関数群です。
提案は、 sort.SliceOf
という sort package への変更という形で出されましたが、Russ Coxのコメントを受けて、slices packageの変更となりました。
Russ Coxのコメント: https://github.com/golang/go/issues/47619#issuecomment-897042602
最終的な形はこちらです。
package slices
func Sort[Elem constraints.Ordered](x []Elem)
func SortFunc[Elem any](x []Elem, less func(a, b Elem) bool)
func SortStable[Elem constraints.Ordered](x []Elem)
func SortStableFunc[Elem any](x []Elem, less func(a, b Elem) bool)
func IsSorted[Elem constraints.Ordered](x []Elem)
func IsSortedFunc[Elem any](x []Elem, less func(a, b Elem) bool)
func BinarySearch[Elem constraints.Ordered](x Slice, target Elem) int
func BinarySearchFunc[Elem any](x []Elem, ok func(Elem) bool) int
spec: generics: type parameters on aliases: accepted (2021/9/23)
spec: allow eliding interface{ } in constraint literals: accepted (2021/10/14)
go/types changes for generics: accepted (2021/10/14)
その他
Discussion
how to update APIs for generics