It makes no difference if v is a non-nil pointer type.
s := "hello" rv := reflect.ValueOf(&s) fmt.Println(rv.Type().Elem() == rv.Elem().Type()) // prints "true"
Here are some examples where rv.Type().Elem() and rv.Elem().Type()) different:
// nil pointer var p *string rv := reflect.ValueOf(p) fmt.Println(rv.Type().Elem()) // prints "string" fmt.Println(rv.Elem().Type()) // panic: call of reflect.Value.Type on zero Value // interface value var i interface{} = "hello" rv := reflect.ValueOf(&i).Elem() fmt.Println(rv.Type()) // prints "interface {}" fmt.Println(rv.Elem().Type()) // prints "string" fmt.Println(rv.Type().Elem()) // panic: Elem of invalid type
If rv.Type().Elem() used in Allocate , then the nil check can be removed, and the function will work with the nil pointer values.
Calling reflect.DeepEqual(s0, s1) returns false because the ptr values ββin the values ββare different. DeepEqual compares unsafe pointers as simple values, not as pointers. This example may help explain what happens:
v := "hello" rv := reflect.ValueOf(&v) s0 := reflect.New(rv.Type().Elem()) s1 := reflect.New(rv.Elem().Type()) s2 := reflect.New(rv.Type().Elem()) s3 := reflect.New(rv.Elem().Type()) fmt.Println(reflect.DeepEqual(s0, s1)) // prints "false" fmt.Println(reflect.DeepEqual(s0, s2)) // prints "false" fmt.Println(reflect.DeepEqual(s1, s3)) // prints "false" fmt.Println(reflect.DeepEqual(s2, s3)) // prints "false" fmt.Println(reflect.DeepEqual(s0.Interface(), s1.Interface())) // prints "true" fmt.Println(reflect.DeepEqual(s0.Interface(), s2.Interface())) // prints "true" fmt.Println(reflect.DeepEqual(s1.Interface(), s3.Interface())) // prints "true" fmt.Println(reflect.DeepEqual(s2.Interface(), s3.Interface())) // prints "true"
As you can see, reflect.Value comparisons are false, even if they were created using the same call sequence.
source share