reflection - reflect.Value.MapIndex() 返回一个不同于 reflect.ValueOf() 的值

标签 reflection go

根据 reflect 文档 reflect.Value.MapIndex() 应返回一个 reflect.Value,它表示存储在 map 特定键处的数据的值.所以我的理解是以下两个表达式应该是相同的。在第一种情况下,我们从 MapIndex() 获取结果。在第二个中,我们从 MapIndex() 获取结果,获取它的基础数据,然后对其执行 reflect.ValueOf()

reflect.ValueOf(map).MapIndex("Key")
reflect.ValueOf(reflect.ValueOf(map).MapIndex("Key").Interface())

为什么需要额外的 reflect.ValueOf()

示例代码:

package main

import "fmt"
import "reflect"

func main() {
    test := map[string]interface{}{"First": "firstValue"}
    Pass(test)
}

func Pass(d interface{}) {
    mydata := reflect.ValueOf(d).MapIndex(reflect.ValueOf("First"))
    fmt.Printf("Value: %+v \n", mydata.Interface())
    fmt.Printf("Kind: %+v \n", mydata.Kind())
    fmt.Printf("Kind2: %+v \n", reflect.ValueOf(mydata.Interface()).Kind())
}

开始玩:http://play.golang.org/p/TG4SzrtTf0

最佳答案

考虑一段时间后,这属于 duh 类别。它与 Go 中 interfaces 的性质有关,它们是指向其他事物的引用对象。我已明确声明我的 map 为 map[string]interface{},这意味着每个键所在位置的值是 interface{},而不是字符串,所以收到一个包含 interface{}reflect.Value 我真的不应该感到惊讶。

额外的 reflect.ValueOf() 深入一层以获得 interface{} 的底层值。我创建了两个示例,我相信这两个示例都证实了这种行为。

使用 map[string]Stringer 自定义接口(interface)的示例:http://play.golang.org/p/zXCn9Fce3Q

package main

import "fmt"
import "reflect"

type Test struct {
    Data string
}

func (t Test) GetData() string {
    return t.Data
}

type Stringer interface {
    GetData() string
}

func main() {
    test := map[string]Stringer{"First": Test{Data: "testing"}}
    Pass(test)
}

func Pass(d interface{}) {
    mydata := reflect.ValueOf(d).MapIndex(reflect.ValueOf("First"))
    fmt.Printf("Value: %+v \n", mydata.Interface())
    fmt.Printf("Kind: %+v \n", mydata.Kind())
    fmt.Printf("Kind2: %+v \n", reflect.ValueOf(mydata.Interface()).Kind())
}

返回

Value: {Data:testing} 
Kind: interface 
Kind2: struct

使用 map[string]string 的示例:http://play.golang.org/p/vXuPzmObgN

package main

import "fmt"
import "reflect"

func main() {
    test := map[string]string{"First": "firstValue"}
    Pass(test)
}

func Pass(d interface{}) {
    mydata := reflect.ValueOf(d).MapIndex(reflect.ValueOf("First"))
    fmt.Printf("Value: %+v \n", mydata.Interface())
    fmt.Printf("Kind: %+v \n", mydata.Kind())
    fmt.Printf("Kind2: %+v \n", reflect.ValueOf(mydata.Interface()).Kind())
}

返回

Value: firstValue 
Kind: string 
Kind2: string 

关于reflection - reflect.Value.MapIndex() 返回一个不同于 reflect.ValueOf() 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14142667/

相关文章:

C# "is"运算符 - 那是反射吗?

c# - 你如何将一个扁平的点状属性列表转换为一个构造的对象?

reflection - 哪些 Scala 功能是在内部使用反射实现的?

c# - 调用继承自封闭泛型的方法信息

reflection - 如何打开 reflect.Type?

go - 如何使用golang发送ACK和ENQ等数据包

go - 在 Programming go 中打勾

python - 无法使用 Python 中的检查通过 exec 获取方法 "declared"的源代码

pointers - 通过函数将指针设置为 nil

go - 检查方法类型是否与函数类型匹配