首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >reflect.Value.MapIndex()返回与reflect.ValueOf()不同的值

reflect.Value.MapIndex()返回与reflect.ValueOf()不同的值
EN

Stack Overflow用户
提问于 2013-01-03 16:10:53
回答 2查看 1.9K关注 0票数 4

根据反射文档,reflect.Value.MapIndex()应该返回一个reflect.Value,它表示存储在映射的特定键上的数据的值。因此,我的理解是,以下两个表达式应该是相同的。在第一种情况下,我们将从MapIndex()获得结果。在第二步中,我们从MapIndex()获得结果,获取底层数据,然后对其执行reflect.ValueOf()

代码语言:javascript
复制
reflect.ValueOf(map).MapIndex("Key")
reflect.ValueOf(reflect.ValueOf(map).MapIndex("Key").Interface())

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

示例代码:

代码语言:javascript
复制
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())
}

Go Play:http://play.golang.org/p/TG4SzrtTf0

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-04 04:32:52

经过一段时间的思考,这属于杜伊范畴。它与Go中interfaces的性质有关,它是指向其他事物的引用对象。我已经显式声明了我的映射为map[string]interface{},这意味着每个键位置的值是一个interface{},而不是一个字符串,所以收到一个包含interface{}reflect.Value并不奇怪。

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

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

代码语言:javascript
复制
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())
}

返回

代码语言:javascript
复制
Value: {Data:testing} 
Kind: interface 
Kind2: struct

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

代码语言:javascript
复制
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())
}

返回

代码语言:javascript
复制
Value: firstValue 
Kind: string 
Kind2: string 
票数 2
EN

Stack Overflow用户

发布于 2013-01-04 04:46:00

代码语言:javascript
复制
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())

在您的程序中,mydata是一个接口,因此,在调用()时,没有意外地报告它是这样的。

代码语言:javascript
复制
    fmt.Printf("Kind2: %+v \n", reflect.ValueOf(mydata.Interface()).Kind())

把这个分解一下:

代码语言:javascript
复制
s := mydata.Interface()  // s is a string
v := reflect.ValueOf(s)  // v is a reflect.Value
k := v.Kind()            // k is a reflect.Kind "string"

我认为您可能会因为映射包含接口而不是字符串这一事实而被绊倒。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14142667

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档