Can you pass a struct fieldname in to a function in golang?

845 Views Asked by At

Say for example you have something like this, trying to make the example as simple as possible.

type Home struct {
    Bedroom string
    Bathroom string
}

How do you pass the field name, or can you, to a function?

func (this *Home) AddRoomName(fieldname, value string) {
    this.fieldname = value
}

Obviously that does not work... The only way I can see to do this is to use two functions which adds a lot of extra code when the struct gets really big and has a lot of similar code.

func (this *Home) AddBedroomName(value string) {
    this.Bedroom = value
}
func (this *Home) AddBathroomName(value string) {
    this.Bathroom = value
}
3

There are 3 best solutions below

0
On

The only way that I am aware of is to use reflection:

func (this *Home) AddRoomName(fieldname, value string) {
    h := reflect.ValueOf(this).Elem()
    h.FieldByName(fieldname).Set(reflect.ValueOf(value))
    return
}

http://play.golang.org/p/ZvtF_05CE_

0
On

One more idea that comes to my mind is like this, not sure if it makes sense in your case though:

func Set(field *string, value string) {
    *field = value
}

home := &Home{"asd", "zxc"}
fmt.Println(home)
Set(&home.Bedroom, "bedroom")
Set(&home.Bathroom, "bathroom")
fmt.Println(home)

http://play.golang.org/p/VGb69OLX-X

0
On

Use type assertions on an interface value:

package main

import "fmt"

type Test struct {
    S string
    I int
}

func (t *Test) setField(name string, value interface{}) {
    switch name {
        case "S":
            t.S = value.(string)
        case "I":
            t.I = value.(int)
    }
}

func main() {
    t := &Test{"Hello", 0}
    fmt.Println(t.S, t.I)
    t.setField("S", "Goodbye")
    t.setField("I", 1)
    fmt.Println(t.S, t.I)
}