How to access unexported struct fields

If the struct is addressable, you can use unsafe.Pointer to access the field (read or write) it, like this:

rs := reflect.ValueOf(&MyStruct).Elem()
rf := rs.Field(n)
// rf can't be read or set.
rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem()
// Now rf can be read and set.

See full example on the playground.

This use of unsafe.Pointer is valid according to the documentation and running go vet returns no errors.

If the struct is not addressable this trick won’t work, but you can create an addressable copy like this:

rs = reflect.ValueOf(MyStruct)
rs2 := reflect.New(rs.Type()).Elem()
rs2.Set(rs)
rf = rs2.Field(0)
rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem()
// Now rf can be read.  Setting will succeed but only affects the temporary copy.

See full example on the playground.

Leave a Comment

tech