patterngoCritical
Access struct property by name
Viewed 0 times
propertystructaccessname
Problem
Here is a simple go program that is not working :
Error:
prog.go:18: invalid operation: v[property] (index of type *Vertex)
What I want is to access the Vertex X property using its name. If I do
Can someone tell me how to make this work ?
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]
}Error:
prog.go:18: invalid operation: v[property] (index of type *Vertex)
What I want is to access the Vertex X property using its name. If I do
v.X it works, but v["X"] doesn't. Can someone tell me how to make this work ?
Solution
Most code shouldn't need this sort of dynamic lookup. It's inefficient compared to direct access (the compiler knows the offset of the X field in a Vertex structure, it can compile v.X to a single machine instruction, whereas a dynamic lookup will need some sort of hash table implementation or similar). It's also inhibits static typing: the compiler has no way to check that you're not trying to access unknown fields dynamically, and it can't know what the resulting type should be.
But... the language provides a reflect module for the rare times you need this.
There's no error checking here, so you'll get a panic if you ask for a field that doesn't exist, or the field isn't of type int. Check the documentation for reflect for more details.
But... the language provides a reflect module for the rare times you need this.
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())
}There's no error checking here, so you'll get a panic if you ask for a field that doesn't exist, or the field isn't of type int. Check the documentation for reflect for more details.
Code Snippets
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())
}Context
Stack Overflow Q#18930910, score: 163
Revisions (0)
No revisions yet.