🤖
Go チルダ(~)[Generics]
Go Gereticsのチルダ(~)
version 1.18よりGenericsが利用可能に。
Go 1.18 Release Notes - The Go Programming Languageリリースノートのサンプルより以下のコードのなかで気になった箇所が。
func Print[T ~int|~string](t T) {
fmt.Printf("%d", t)
}
T
型パラメータの型の前についている、~
は何...?
それを探るべく我々はGo Specへ向かった。
Underlying Type
Interface typesの説明に、以下のような構文木の定義がある。
InterfaceType = "interface" "{" { InterfaceElem ";" } "}" .
InterfaceElem = MethodElem | TypeElem .
MethodElem = MethodName Signature .
MethodName = identifier .
TypeElem = TypeTerm { "|" TypeTerm } .
TypeTerm = Type | UnderlyingType .
UnderlyingType = "~" Type .
一番下の行~
は、Underlying Type というものらしい。
Underlying Typeに関しては、この説明が一番わかりやすかった。
入門Go言語仕様 Underlying Type / Go Language Underlying Type - Speaker Deck
Underlying Typeはその型の基礎となる型のことで、最初の~int
の例は、基礎となる型がint
である型を要求する、ということ。
つまり、こういうことができる。
package main
import "fmt"
type MyInt int
type MyString string
type MyExtendedString MyString
func Print[T ~int | ~string](t T) {
fmt.Printf("%d", t)
}
func main() {
Print(MyInt(1))
Print(MyString("foo"))
Print(MyExtendedString("bar"))
}
Underlying Typeが一致する独自型を渡すことができるということ。
その他の参考
型仕様周りは奥が深いので、少し掘り下げることにする。
Discussion