Goのポインターリフレクションの奇妙な動作を理解するために、3つの同様の関数を作成しました。
package main
import (
"reflect"
"fmt"
)
var i interface{} = struct {}{} // i is an interface which points to a struct
var ptr *interface{} = &i // ptr is i's pointer
func f(x interface{}) { // print x's underlying value
fmt.Println(reflect.ValueOf(x).Elem())
}
func main1() { // f is asking for interface? OK, I'll use the struct's interface
structValue := reflect.ValueOf(ptr).Elem().Elem().Interface()
f(structValue)
}
func main2() { // Error? Let me try the struct's pointer
structPtr := reflect.ValueOf(ptr).Elem().Interface()
f(structPtr)
}
func main3() { // Why this one could succeed after New() ?
typ := reflect.ValueOf(ptr).Elem().Elem().Type()
newPtr := reflect.New(typ).Elem().Addr().Interface()
f(newPtr)
}
func main() {
//main1() // panic: reflect: call of reflect.Value.Elem on struct Value
//main2() // panic: reflect: call of reflect.Value.Elem on struct Value
main3() // OK. WHY???
}
main3 だけが機能しており、他の 2 つはパニックに陥ります。なんで?3 の主な違いは、新しい価値を生み出すことです。
ValueOf().Elem().Interface()
main2 に関しては、を指すインターフェイスを既に再構築していると思いますがstruct{}{}
、なぜ失敗するのか理解できません。