v.Type()。Elem()和v.Elem()。Type()有什么区别?

In the following code, both options seem to allocate the same resource

func Allocate(v interface{}) error {
    rv := reflect.ValueOf(v)
    if rv.IsNil() {
        return errors.New("Value of v is nil")
    }
    s0 := reflect.New(rv.Type().Elem())
    s1 := reflect.New(rv.Elem().Type())

    return errors.New(fmt.Sprintf("What's the diff? %v %v", s0, s1))
}

If there's no difference in this specific example, an example illustrating the difference will be great. Also what's the preferable option in this specific case when trying to allocate for an interface.

Edit: reflect.DeepEqual(s0, s1) returns false. I think rv.Elem().Type() has a problem dealing with zero values so maybe rv.Type().Elem() is preferred.

Playground

There is 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()) are 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() is used in Allocate, then the nil check can be removed and the function will work with nil pointer values.

The call reflect.DeepEqual(s0, s1) returns false because the ptr fields in the values are different. DeepEqual compares unsafe pointers as simple values, not as pointers. This example might help explain what's going on:

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, the reflect.Value comparisons are all false, even when created using the same sequence of calls.