Reflect
With reflect we get information about our variables at runtime.
It's highly recommended not to use reflection, because every wrong usage can panic
.
Reflect should be the last possible way to do "meta-programming" in Go.
But let's check an example anyway:
output:
Reflection has three rules, that you should remember, when you work with reflect
:
- Reflection goes from interface value to reflection object
- Reflection goes from reflection object to interface value
- To modify a reflection object, the value must be settable
Reflection goes from interface value to reflection object
If you use reflect.TypeOf
you pass in any
and get a Type
back.
Type
is an interface to get more information about the reflected type.
If we want to examine the Value
of a specific variable we can do that by:
We can use the reflection to check, if a variable has a specific type:
output would be:
If you have a user-defined type, Type
can give you the user-defined type, but Kind
will always give you the built-in type.
Reflection goes from reflection object to interface value
If we have a reflected reflect.Value
, we can derive back the inverse of it.
We call the Interface
method on a Value
to get it's interface again and then we can Type Assert it back to it's natural Go type.
Let's take an example:
output:
To modify a reflection object, the value must be settable
To set a value via reflection, the value must be settable.
output:
Go is call-by-value, therefore it's a copy of the variable x
what reflect.ValueOf
is using.
When we want to set the value of x
, we have to pass a "Setable" type: a pointer.
If we now to set the value, the output would be:
Why? Because we just try to set 7.1 to the pointer itself and not to the actual value in RAM.
To get the actual Value of a pointer in the RAM we have to call [Elem
].
Elem returns the value that the interface v contains or that the pointer v points to. It panics if v's Kind is not Interface or Pointer. It returns the zero Value if v is nil.
Example:
now the output is correct: