Reflection
Mit Reflection kann ein Programm seine eigene Struktur auslesen und verändern. Allerdings ist die Ausführung von Programmen, die Reflection verwenden, um einiges langsamer. Viele Programmiersprache darunter auch Smalltalk, C# oder Java bieten solche Funktionen an. Auch Go hat mit dem Paket reflect
ebenfalls diese Möglichkeit.
Das nachfolgende Beispiel zeigt wie man Wert und Typ eines primitiven Datentyps ausliest. Dazu muss man das Paket reflect
importieren.
var i int = 10
reflect.ValueOf(i) // 10
reflect.TypeOf(i) // int
Möchte man einen Wert per Reflection verändern, wäre der erste Ansatz vielleicht folgender.
var i int = 10
v := reflect.ValueOf(i)
v.SetInt(1)
Dieser Versuch verursacht aber einen Fehler. Weil die Variable i
als Kopie an die Methode ValueOf()
übergeben wurde, ist der Wert von i
nicht adressierbar. Anstatt eine Kopie von i
zu übergeben könnte man auch die Adresse von i
übergeben (ein Pointer). Durch &
vor dem i
wird die Adresse übergeben, wie man im nachfolgenden Beispiel sehen kann.
var i int = 10
v := reflect.ValueOf(&i)
v.SetInt(1)
Doch auch dieser Versuch generiert einen Fehler. Das Problem ist dass man den Wert von der Variable v
setzen möchte. Diese ist aber vom Typ reflect.Value
und nicht vom Typ int
. Das nachfolgende Beispiel zeigt wie man den Wert korrekt setzt.
var i int = 10
v := reflect.ValueOf(&i)
e := v.Elem()
e.SetInt(1)
Man muss den Wert also auf dem Element verändern. Um zu überprüfen ob sich ein Wert per Reflection verändern lässt gibt es die Methode CanSet()
.
Die Reflection von Go unterstützt auch Structs und damit lassen sich viele Dinge anstellen, die aber den Rahmen sprengen würden.
- Pike, Rob (2011), The Laws of Reflection. Gefunden unter: http://blog.golang.org/laws-of-reflection