Here's the working version of f:
func f(i interface{}) { v := reflect.ValueOf(i).Elem().FieldByName("Id") ptr := v.Addr().Interface().(*int) *ptr = 100 }
playground example
The conversion to an integer pointer is as follows:
v is reflect.Value representing the int field.v.Addr() is a relfect.Value representing a pointer to an int field.v.Addr().Interface() is an interface{} containing an int pointer.v.Addr().Interface().(*int) type asserts interface{} on *int
You can set the field directly without specifying a pointer:
func f(i interface{}) { v := reflect.ValueOf(i).Elem().FieldByName("Id") v.SetInt(100) }
playground example
If you pass a value while waiting for the {} interface (for example, db / sql Scan methods), you can remove the statement like:
func f(i interface{}) { v := reflect.ValueOf(i).Elem().FieldByName("Id") scan(v.Addr().Interface()) }
playground example
source share