在以下代码中,两个选项似乎都分配了相同的资源
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))
}
Run Code Online (Sandbox Code Playgroud)
如果这个具体例子没有区别,那么说明差异的例子就会很棒.此外,在尝试分配接口时,此特定情况下的首选选项是什么.
编辑:reflect.DeepEqual(s0,s1)返回false.我认为rv.Elem().Type()有一个处理零值的问题,所以可能是rv.Type().Elem()是首选.
如果v是非零指针类型则没有区别.
s := "hello"
rv := reflect.ValueOf(&s)
fmt.Println(rv.Type().Elem() == rv.Elem().Type()) // prints "true"
Run Code Online (Sandbox Code Playgroud)
下面是一些例子,其中rv.Type().Elem()和rv.Elem().Type())是不同的:
// 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
Run Code Online (Sandbox Code Playgroud)
如果rv.Type().Elem()使用Allocate,则可以删除nil检查,该函数将使用nil指针值.
调用reflect.DeepEqual(s0, s1)返回false,因为值中的ptr字段不同. DeepEqual比较不安全指针作为简单值,而不是指针.这个例子可能有助于解释发生了什么:
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"
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,即使使用相同的调用序列创建,reflect.Value比较也都是错误的.
| 归档时间: |
|
| 查看次数: |
942 次 |
| 最近记录: |