一尘不染

按名称访问结构属性

go

这是一个不起作用的简单 go 程序:

package main
import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    fmt.Println(getProperty(&v, "X"))
}

func getProperty(v *Vertex, property string) (string) {
    return v[property]
}

错误:

prog.go:18: 无效操作:v[property](*Vertex 类型的索引)

我想要的是使用其名称访问 Vertex X 属性。如果我这样做,v.X它会起作用,但v["X"]不会。

有人可以告诉我如何进行这项工作吗?


阅读 142

收藏
2021-12-12

共1个答案

一尘不染

大多数代码不应该需要这种动态查找。与直接访问相比,它效率低下(编译器知道 Vertex 结构中 X 字段的偏移量,它可以将 vX 编译为单个机器指令,而动态查找将需要某种哈希表实现或类似的实现)。它还禁止静态类型:编译器无法检查您是否尝试动态访问未知字段,并且它无法知道结果类型应该是什么。

但是......该语言为您很少需要它的情况提供了一个反射模块。

package main

import "fmt"
import "reflect"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    fmt.Println(getField(&v, "X"))
}

func getField(v *Vertex, field string) int {
    r := reflect.ValueOf(v)
    f := reflect.Indirect(r).FieldByName(field)
    return int(f.Int())
}

这里没有错误检查,所以如果你请求一个不存在的字段,或者该字段不是 int 类型,你会感到恐慌。查看文档以获取更多详细信息。

2021-12-12