GoLang:按名称访问结构属性
这是一个简单的去程序不工作:
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: invalid operation: v[property] (index of type *Vertex)
我想要的是访问使用其名称的顶点X属性。 如果我做vX
话,但是v["X"]
没有。
有人能告诉我如何使这项工作?
大多数代码不应该需要这种dynamic查找。 与直接访问(编译器知道Vertex结构中的X字段的偏移量,它可以将vX编译成单个机器指令,而dynamic查找需要某种types的哈希表实现或类似方法)相比,效率低下。 它也禁止静态types:编译器没有办法检查你是不是试图dynamic访问未知的字段,它不知道结果types应该是什么。
但是…这个语言为你需要这个难得的时代提供了一个反映模块。
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()) }
这里没有错误检查,所以如果你要求一个不存在的字段,或者这个字段不是inttypes的话,你会感到恐慌。 查看reflection的文档以获取更多详细信息。
Yuo现在有项目oleiade /reflection ,它允许您获取/设置结构值或指针字段。
这使得使用reflect
包不那么棘手。
s := MyStruct { FirstField: "first value", SecondField: 2, ThirdField: "third value", } fieldsToExtract := []string{"FirstField", "ThirdField"} for _, fieldName := range fieldsToExtract { value, err := reflections.GetField(s, fieldName) DoWhatEverWithThatValue(value) } // In order to be able to set the structure's values, // a pointer to it has to be passed to it. _ := reflections.SetField(&s, "FirstField", "new value") // If you try to set a field's value using the wrong type, // an error will be returned err := reflection.SetField(&s, "FirstField", 123) // err != nil