dtczp02204 2017-03-28 16:25
浏览 35
已采纳

在Go中获取substruct字段

I am trying to get fields from a struct value using reflection.

package main

import (
    "fmt"
    "reflect"
)

type Vertex struct {
    X         string
    Y         string
    SubVertex SubVertex
}
type SubVertex struct {
    Z string
}

func get_field(v Vertex, field string) string {
    r := reflect.ValueOf(v)
    f := reflect.Indirect(r).FieldByName(field)
    return f.String()
}

func main() {
    v := Vertex{"a", "b", SubVertex{"c"}}

    fmt.Println(get_field(v, "X"))
    fmt.Println(get_field(v, "Y"))
    fmt.Println(get_field(v, "Z"))  // Invalid Value
}

I get Invalid Value in the third case, when I try to get the value of the Z field. If SubVertex were an anonymous field, this would work, but I need to use a named field.

How do I make this work?

  • 写回答

1条回答 默认 最新

  • dpgkg42484 2017-03-28 17:14
    关注

    In this case, you have to use the reflect package in the same manner as you would accessing the values normally. So

    v.X // a
    v.Y // b
    v.SubVertex.Z // c
    

    becomes

    r := reflect.ValueOf(v)
    x := reflect.Indirect(r).FieldByName("X")
    x.String() // a
    ...
    z := reflect.Indirect(r).FieldByName("SubVertex").FieldByName("Z")
    z.String() // c
    

    Note that FieldByName() is called on a Value and returns a Value, so it works much the same as just accessing it regularly. Also note that as per the documentation:

    Indirect returns the value that v points to. If v is a nil pointer, Indirect returns a zero Value. If v is not a pointer, Indirect returns v.

    So the call to Indirect() would be a No-op, but would protect it from having a meltdown if you decided to give it a pointer in the future.

    As for your function, this would work

    func get_field(v Vertex, field string) string {
        r := reflect.ValueOf(v)
        if field == "Z" {
            f := reflect.Indirect(r).FieldByName("SubVertex").FieldByName(field)
            return f.String()
        }
        f := reflect.Indirect(r).FieldByName(field)
    
        return f.String()
    }
    

    https://play.golang.org/p/eZyTl8OSTZ

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题