什么时候反映.IsValid返回false?

ysk*_*kyj 5 reflection go

我对IsValid功能感到好奇,因为在我使用这个功能时,它从未返回过false.那么它何时会返回否定结果呢?

icz*_*cza 8

正如文件reflect.IsValid()所说:

如果v为零值,则返回false.[...]大多数函数和方法永远不会返回无效值.如果有,它的文档明确说明条件.

Value.IsValid()应该报告reflect.Value它本身是否有效,而不是它包装的值(如果有的话).

以下所有示例都打印出来false.您可以在Go Playground上试试.

最简单的例子是调用IsValid()零值reflect.Value(这是一个struct):

fmt.Println(reflect.Value{}.IsValid())
Run Code Online (Sandbox Code Playgroud)

第二个最简单的例子是传递nilreflect.ValueOf():

fmt.Println(reflect.ValueOf(nil).IsValid())
Run Code Online (Sandbox Code Playgroud)

另一个例子:以指针开始nil,在这种情况下没有"尖"值,nil指针指向无处.尝试获取reflect.Value指向值使用的Value.Elem()结果为零,reflect.ValueIsValid()方法将返回false:

var i *int
v := reflect.ValueOf(i)
v2 := v.Elem()
fmt.Println(v2.IsValid())
Run Code Online (Sandbox Code Playgroud)

或者在一行中:

fmt.Println(reflect.ValueOf((*int)(nil)).Elem().IsValid())
Run Code Online (Sandbox Code Playgroud)

如果你打电话Value.Indirect()给上面的话也一样reflect.Value():

fmt.Println(reflect.Indirect(v).IsValid())
Run Code Online (Sandbox Code Playgroud)

或者尝试使用以下命令获取不存在的struct字段Value.FieldByName():

s := struct{}{}
fmt.Println(reflect.ValueOf(s).FieldByName("").IsValid())
Run Code Online (Sandbox Code Playgroud)

或者尝试使用以下命令获取名称不存在的方法Value.MethodByName():

fmt.Println(reflect.ValueOf(s).MethodByName("").IsValid())
Run Code Online (Sandbox Code Playgroud)

或者尝试使用Value.MapIndex()以下方法通过不存在的键从地图获取值:

m := map[int]int{}
fmt.Println(reflect.ValueOf(m).MapIndex(reflect.ValueOf(3)).IsValid())
Run Code Online (Sandbox Code Playgroud)

名单继续......