Mahdi.Kh
September 21, 2026
We get familiar with reflection in Go and learn how to use reflection.
Reflection in programming is a capability that lets a program obtain information about its own structure at runtime — such as data types, variables, and functions — and even modify or call them. In simpler terms, reflection means a program can examine or manipulate itself at runtime.
Reflection is usually slower and can make the code's structure and understanding more complex. For this reason, it's recommended to use it only when necessary.
For this post's content, we used The laws of reflection and added some supplementary notes to it.
In Go, you can use reflection through the reflect package. This package is built around three general concepts:
kind
type
value
To understand the meaning of each of these concepts, let's use an example:
In the example above, we defined and assigned values to three variables, x, y, and z, and then, using reflection, printed their value, type, and kind on the screen.
x variable has a value of 10. Its type is int and its kind is also int.y variable has a value of [2, 4, 6]. Its type is [ ]int and its kind is slice.z variable has a value of {Barfi 3}. Its type is Barfi and its kind is struct.Type specifies the precise definition of a data type, including the data type's name and its structural details, while kind specifies only the type's underlying structure.
In the example above, we defined two data types, Time and Duration. These two data types have different types, but the kind of both of them is int64. So even if we have completely identical data, if their data type has a different name, their Type is different.
Reflection in the Go language is built around three laws:
Through an interface, you can get to a reflection object.
Through a reflection object, you can get to an interface.
To modify a reflection object, that object must be settable.
There are two kinds of reflection objects. One is of type Value and the other is of type Type. Through the reflect.ValueOf method, you can access an interface's Value, and similarly, through the reflect.TypeOf method, you can access an interface's Type and Kind.
Through a reflect.Value object, you can access the interface. In the example below, we convert a reflect.Value object back to the original data type, which is [ ]int.
So, as in the example above, through the Interface method, you can get to the original interface and then use a type assertion to convert that value to its original value.
The reflect.Value object has methods whose names start with Set. For example, SetInt is one of them. Depending on the original data type, you can change the data's value using these methods, but before doing so, you need to make sure the reflection object is settable!
The code above will run into an error, because running SetFloat triggers a panic, and the program's execution terminates. This error occurs because our object isn't settable. You can check whether an object is settable with the CanSet method.
Setting (Set) a value on an object that isn't settable causes an error (panic).
To have a settable object, we need to pass a pointer to the ValueOf function (using &), and then, using the Elem method, we can access the value the pointer points to and set it:
We can also use the Set method:
The value we set on the variable must have the same data type; otherwise, the program's execution will run into an error.
One very useful function you can find inside the reflect package is called DeepEqual. This function takes two input parameters, and if the values of these two parameters are equal, it returns true; otherwise, it returns false.
I recommend taking a quick look at the reflect package's list of functions.
Previous part: Packages and Modules | Golang basics