通过反射提取通用结构值

我正在尝试将结构的所有值提取到字符串切片中。


func structValues(item Item) []string {

    values := []string{}

    e := reflect.ValueOf(&item).Elem()


    for i := 0; i < e.NumField(); i++ {

        fieldValue := e.Field(i).Interface()

        values = append(values, fmt.Sprintf("%#v", fieldValue))

    }

    return values

}

我想将此函数与任何结构一起使用,所以我想我可以将类型签名更改为,func structValues(item interface{})但后来我感到恐慌:


恐慌:反射:在接口值上调用反射.Value.NumField


工作示例:https ://repl.it/@fny/stackoverflow61719532



繁华开满天机
浏览 165回答 1
1回答

噜噜哒

我想将此函数与任何结构一起使用...您可以这样做,但请注意它放弃了类型安全。此外,这样做的唯一方法是允许使用任何类型的调用,而不仅仅是某种结构类型的任何类型,所以你必须检查你得到的实际上是某种结构类型:func structValues(item interface{}) {&nbsp; &nbsp; if reflect.ValueOf(item).Kind() != reflect.Struct {&nbsp; &nbsp; &nbsp; &nbsp; ... do something here ...&nbsp; &nbsp; }进行了检查——或者稍微推迟它,或者省略它以允许reflect恐慌——然后你需要reflect.ValueOf(&item).Elem()用更简单的reflect.ValueOf(item).如果您希望允许指向结构以及实际结构的指针,您可以通过使用reflect.Indirectfirst. 结果是:func structValues(item interface{}) []string {&nbsp; &nbsp; e := reflect.Indirect(reflect.ValueOf(item))&nbsp; &nbsp; if e.Kind() != reflect.Struct {&nbsp; &nbsp; &nbsp; &nbsp; panic("not a struct")&nbsp; &nbsp; }&nbsp; &nbsp; values := []string{}&nbsp; &nbsp; for i := 0; i < e.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; fieldValue := e.Field(i).Interface()&nbsp; &nbsp; &nbsp; &nbsp; values = append(values, fmt.Sprintf("%#v", fieldValue))&nbsp; &nbsp; }&nbsp; &nbsp; return values}reflect.Indirect如果您想确保调用者在有指针时执行自己的间接操作,请忽略。(注意panic这里不是很友好。如果你想要正确的调试,考虑直接用%vor打印结构%#v,或者更彻底的东西,spew 包。)Go Playground 上的完整示例使用您type Item struct自己的链接。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go