[英]When is go reflect CanInterface false?
As per this playground example ( https://play.golang.org/p/Jr64yE4zSpQ ), and the implementation of CanInterface
in reflect/value.go
, it looks like CanInterface
is false only for private fields?根据这个游乐场示例 ( https://play.golang.org/p/Jr64yE4zSpQ ),以及CanInterface
在reflect/value.go
中的实现,看起来CanInterface
仅对私有字段为 false?
What are other scenarios when CanInterface
is false?当CanInterface
为 false 时,还有哪些其他场景?
Playground example:游乐场示例:
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)
reflect/value.go反映/价值.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
}
If you dive into the source code for CanInterface
, you can see this line:如果深入研究CanInterface
的源代码,您会看到这一行:
return v.flag&flagRO == 0
And a bit below it, this block of code from the function valueInterface
:在它的下方,这段代码来自 function 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")
}
Since v.flag&flagRO != 0
is equivalent to !CanInterface
, we can conclude from the comment below it that CanInterface
is false when the reflect.Value
is an unexported struct field or method.由于v.flag&flagRO != 0
等同于!CanInterface
,我们可以从下面的注释中得出结论,当reflect.Value
是未导出的结构字段或方法时, CanInterface
为 false。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.