reflect.ValueOf()
is a function, think of it as the entry point to reflection. When you have a "non-reflection" value, such as a string
or int
, you can use reflect.ValueOf()
to get a reflect.Value
descriptor of it.
Value.Elem()
is a method of reflect.Value
. So you can only use this if you already have a reflect.Value
. You may use Value.Elem()
to get the value (reflect.Value
) pointed by the value wrapped by the original reflect.Value
. Note that you may also use reflect.Indirect()
for this. There's another "use case" for Value.Elem()
, but it's more "advanced", we return to it at the end of the answer.
To "leave" reflection, you may use the general Value.Interface()
method, which returns you the wrapped value as an interface{}
.
For example:
var i int = 3
var p *int = &i
fmt.Println(p, i)
v := reflect.ValueOf(p)
fmt.Println(v.Interface()) // This is the p pointer
v2 := v.Elem()
fmt.Println(v2.Interface()) // This is i's value: 3
This will output (try it on the Go Playground):
0x414020 3
0x414020
3
For a great introduction to Go's reflection, read The Go Blog: The Laws of Reflection. Although if you're just starting with Go, I'd focus on other things and leave reflection for a later adventure.
Another use case for Value.Elem()
This is kind of an advanced topic, so don't freak out if you don't understand it. You don't need to.
We saw how Value.Elem()
can be used to "navigate" when a pointer is wrapped in the reflect.Value
. Doc of Value.Elem()
says:
Elem returns the value that the interface v contains or that the pointer v points to.
So if reflect.Value
wraps an interface value, Value.Elem()
may also be used to get the concrete value wrapped in that interface value.
Interfaces in Go is its own topic, for the internals, you may read Go Data Structures: Interfaces by Russ Cox. Again, not necessarily a topic for Go starters.
Basically whatever value you pass to reflect.ValueOf()
, if it's not already an interface value, it will be wrapped in an interface{}
implicitly. If the passed value is already an interface value, then the concrete value stored in it will be passed as a interface{}
. This second "use case" surfaces if you pass a pointer to interface (which is otherwise very rare in Go!).
So if you pass a pointer to interface, this pointer will be wrapped in an interface{}
value. You may use Value.Elem()
to get the pointed value, which will be an interface value (not a concrete value), and using Value.Elem()
again on this will give you the concrete value.
This example illustrates it:
var r io.Reader = os.Stdin // os.Stdin is of type *os.File which implements io.Reader
v := reflect.ValueOf(r) // r is interface wrapping *os.File value
fmt.Println(v.Type()) // *os.File
v2 := reflect.ValueOf(&r) // pointer passed, will be wrapped in interface{}
fmt.Println(v2.Type()) // *io.Reader
fmt.Println(v2.Elem().Type()) // navigate to pointed: io.Reader (interface type)
fmt.Println(v2.Elem().Elem().Type()) // 2nd Elem(): get concrete value in interface: *os.File
Try it on the Go Playground.