2

如果我有一个结构并且我想获得它的关键,但它目前是类型interface{},我该怎么做?

目前我收到以下编译错误:

invalid operation: d[label] (index of type interface {})

播放:http ://play.golang.org/p/PLr91d55GX

package main

import "fmt"
import "reflect"

type Test struct {
    s string
}

func main() {
    test := Test{s: "blah"}
    fmt.Println(getProp(test, "s"))
}

func getProp(d interface{}, label string) (interface{}, bool) {
    switch reflect.TypeOf(d).Kind() {
    case reflect.Struct:
        _, ok := reflect.TypeOf(d).FieldByName(label)
        if ok {
                    // errors here because interface{} doesn't have index of type 
            return d[label], true
        } else {
            return nil, false
        }
    }
}

我真的必须对每种不同的类型做大量的案例陈述并调用反映的reflect.ValueOf(x).String()等吗?我希望有一种更优雅的方式。

4

2 回答 2

2

你可以这样做,但我认为只有当你的结构成员是一个导出的字段时它才会起作用(即在你的例子中s使用大写字母)S

func getProp(d interface{}, label string) (interface{}, bool) {
    switch reflect.TypeOf(d).Kind() {
    case reflect.Struct:
        v := reflect.ValueOf(d).FieldByName(label)
             return v.Interface(), true
    }
   return nil, false
}

(+ 更多错误处理)

于 2012-12-13T10:18:15.093 回答
0

我不确定您要查找的确切内容,但有一种稍微简单的方法可以查找 interface{} 类型。在您的情况下,您可以使用:

switch val := d.(type) {
  case Test:
    fmt.Println(d.s)
}

显然,我没有做和你一样的事情,但想法是你可以用“d.(type)”检查类型,一旦“case Test:”确定它是你的测试类型的结构,您可以这样访问它。

不幸的是,这并没有解决通过标签访问结构内值的问题,但它至少是一种更优雅的确定类型的方法,@nos 展示了如何使用

v := reflect.ValueOf(d).FieldByName(label)
return v.Interface(), true
于 2012-12-13T16:23:15.763 回答