Goの関数アドレスは型パラメータ毎に別の型として扱われる
Goのreflect.Value.Pointerは基本的に関数のアドレスを返すが、ジェネリックな関数を型パラメータでインスタンス化(instantiate)したとき、そのアドレスは型パラメータごとに異なる。型引数が同じ型であっても異なるアドレスになる。
ただし、Goのreflectで同じ型かどうかを検査するで書いたように、ジェネリックな関数の場合でもreflect.Typeは同じ型として扱われる。型引数が異なっていれば当然だけどreflect.Typeも異なる。
package main
import ( "fmt" "reflect")
func M[T any](v T) { fmt.Println(v)}
func helloT[T any]() { v := reflect.ValueOf(M[T]) fmt.Println("helloT:", v.Pointer())}
func hello[T any]() { v1 := reflect.ValueOf(M[int]) v2 := reflect.ValueOf(M[T]) v3 := reflect.ValueOf(M[byte]) fmt.Println("hello1:", v1.Pointer()) fmt.Println("hello2:", v2.Pointer()) helloT[T]() fmt.Println("same:", v1.Type() == v2.Type()) fmt.Println("diff:", v3.Type() == v2.Type())}
func main() { fmt.Println("main:", reflect.ValueOf(M[int]).Pointer()) hello[int]()
// Output: // main: 4720544 // hello1: 4720544 // hello2: 4719840 // helloT: 4720000 // same: true // diff: false}以下の場合は同じ型として扱われる。
- 異なる関数で
F[T](Tが同じ) - 異なるパッケージで
F[T](Tが同じ) - 異なるモジュールで
F[T](Tが同じ)