Go の interface と Generics の内部構造と進化
interface{} / any の内部実装
code:src/runtime/runtime2.go
type eface struct {
_type *_type
data unsafe.Pointer
}
code:src/runtime/type.go
type _type = abi.Type
_type と data の両方が nil になる時だけ、nil とイコールであると判断される
interface の内部実装
code:src/runtime/runtime2.go
type itab = abi.ITab
type iface struct {
tab *itab
data unsafe.Pointer
}
eface 同様、tab と data が nil になる時だけ、nil とイコールであると判断される
itab: メソッドポインタの配列
実体型と interface のメソッドセットを対応付けする
code:src/internal/abi/iface.go
type ITab struct {
Inter *InterfaceType // 実装しているインタフェース型。
Type *Type // 基底型となる具象型。
Hash uint32 // Type.Hash のコピー。型スイッチ時に利用。
Fun 1uintptr // Fun0 == 0 の場合、Type が Inter を実装していないことを表す。 }
code:code:src/internal/abi/type.go
type InterfaceType struct {
Type
PkgPath Name // パッケージのインポートパス
Methods []Imethod // ハッシュによって並び替えられる
}
ABI = Application Binary Interface。型情報やインタフェース表現など低レベルなデータ構造。 空インタフェースと具象インタフェースのコンパイル時の型情報
code:src/internal/abi/.go
type EmptyInterface struct {
Type *Type // 基底型のみ保有し、メソッドは持っていない
Data unsafe.Pointer
}
type NonEmptyInterface struct {
ITab *ITab // ITab 内で基底型とメソッドの両方を持っている
Data unsafe.Pointer
}
コンパイラは、具体的な型を持つ引数で実行されるジェネリック関数およびインスタンス化を行う
加えて、辞書を使って純粋な モノモーフィゼーション を避けて、1 つの関数インスタンスを複数の型で動かせるようにしている ∵ コードサイズの節約
内部実装
コンパイラ
Instantiate 関数でジェネリック型や関数に具体的な型引数を適用してインスタンス化する
code:src/cmd/compile/internal/types2/instantiate.go
// orig(オリジナルの型)は、型エイリアス、定義型、関数型のいずれかである必要がある
func Instantiate(ctxt *Context, orig Type, targs []Type, validate bool) (Type, error) {
...
if validate {
tparams := orig_.TypeParams().list()
...
if i, err := (*Checker)(nil).verify(nopos, tparams, targs, ctxt); err != nil {
return nil, &ArgumentError{i, err}
}
}
inst := (*Checker)(nil).instance(nopos, orig_, targs, nil, ctxt)
return inst, nil
}
辞書
code:src/cmd/compile/internal/noder/reader.go
type readerDict struct {
shaped bool
baseSym *types.Sym
shapedObj *ir.Name
targs []*types.Type
implicits int
derived []derivedInfo
derivedTypes []*types.Type
typeParamMethodExprs []readerMethodExprInfo
subdicts []objInfo
rtypes []typeInfo
itabs []itabInfo
}
https://gyazo.com/3c1f7bae4de081fb7a60a236f4b36d59
参考