Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access struct property by name

Tags:

go

go-reflect

Here is a simple go program that is not working :

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 ?

like image 598
Nicolas BADIA Avatar asked Sep 21 '13 09:09

Nicolas BADIA


People also ask

How do I access struct properties?

A struct variable can be declared either on its own or as part of the struct definition. We access a struct property member with dot notation ( . ). We access a struct pointer member with arrow notation ( -> ).

How do I access struct members in go?

To access individual fields of a struct you have to use dot (.) operator.

How to access struct of an object?

It is easy to access the variable of C++ struct by simply using the instance of the structure followed by the dot (.) operator and the field of the structure.

Does Go have struct?

Go's structs are typed collections of fields. They're useful for grouping data together to form records. This person struct type has name and age fields.


1 Answers

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.

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.

like image 159
Paul Hankin Avatar answered Sep 29 '22 21:09

Paul Hankin