go 反射 CanInterface 什么时候为 false?

U A*_*los 3 reflection go

根据这个游乐场示例(https://play.golang.org/p/Jr64yE4zSpQCanInterface )和in的实现reflect/value.go,看起来CanInterface仅对于私有字段来说是 false ?

当 为 false 时,还有哪些其他情况CanInterface

游乐场示例:

num := 6
meta := reflect.ValueOf(num)
fmt.Println("canInterface:", meta.CanInterface() == true)

meta = reflect.ValueOf(&num)
fmt.Println("canInterface:", meta.CanInterface() == true)

foo := Foo{}
meta = reflect.ValueOf(&foo)
fmt.Println("canInterface:", meta.CanInterface() == true)
meta = meta.Elem()
fmt.Println("canInterface:", meta.CanInterface() == true)
publicField := meta.FieldByName("Number")
privateField := meta.FieldByName("privateNumber")
fmt.Println(
    "canInterface:", 
    publicField.CanInterface() == true,
    // Woah, as per the implementation (reflect/value.go) 
    // this is the only time it can be false
    privateField.CanInterface() != true)

var fooPtr *Foo
var ptr anInterface = fooPtr
meta = reflect.ValueOf(ptr)
fmt.Println("canInterface:", meta.CanInterface() == true)

meta = reflect.ValueOf(&foo)
meta = meta.Elem() // ptr to actual value
publicField = meta.FieldByName("Number")
ptrToField := publicField.Addr()
fmt.Println("canInterface:", ptrToField.CanInterface() == true)
Run Code Online (Sandbox Code Playgroud)

反映/value.go

func (v Value) CanInterface() bool {
if v.flag == 0 {
    panic(&ValueError{"reflect.Value.CanInterface", Invalid})
}
// I think "flagRO" means read-only?
return v.flag&flagRO == 0
}
Run Code Online (Sandbox Code Playgroud)

Mos*_*vah 5

如果你深入研究 的源代码CanInterface,你可以看到这一行:

return v.flag&flagRO == 0
Run Code Online (Sandbox Code Playgroud)

在它的下面,是函数中的这段代码valueInterface

if safe && v.flag&flagRO != 0 {
    // Do not allow access to unexported values via Interface,
    // because they might be pointers that should not be
    // writable or methods or function that should not be callable.
    panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
}
Run Code Online (Sandbox Code Playgroud)

由于v.flag&flagRO != 0相当于!CanInterface,我们可以从它下面的注释得出结论,当是未导出的结构体字段或方法时,它CanInterface是错误的。reflect.Value