- Go Systems Programming
- Mihalis Tsoukalos
- 447字
- 2021-07-02 18:08:02
Reflection
Reflection is an advanced Go feature that allows you to dynamically learn the type of an arbitrary object as well as information about its structure. You should recall that the dataStructures.go program from Chapter 2, Writing Programs in Go, used reflection to find out the fields of a data structure as well as the type of each fields. All of this happened with the help of the reflect Go package and the reflect.TypeOf() function that returns a Type variable.
Reflection is illustrated in the reflection.go Go program that will be presented in four parts.
The first one is the preamble of the Go program and has the following code:
package main import ( "fmt" "reflect" )
The second part is as follows:
func main() { type t1 int type t2 int x1 := t1(1) x2 := t2(1) x3 := 1
Here, you create two new types, named t1 and t2, that are both int and three variables, named x1, x2, and x3.
The third part has the following Go code:
st1 := reflect.ValueOf(&x1).Elem() st2 := reflect.ValueOf(&x2).Elem() st3 := reflect.ValueOf(&x3).Elem() typeOfX1 := st1.Type() typeOfX2 := st2.Type() typeOfX3 := st3.Type() fmt.Printf("X1 Type: %s\n", typeOfX1) fmt.Printf("X2 Type: %s\n", typeOfX2) fmt.Printf("X3 Type: %s\n", typeOfX3)
Here, you find the type of the x1, x2, and x3 variables using reflect.ValueOf() and Type().
The last part of reflection.go deals with a struct variable:
type aStructure struct { X uint Y float64 Text string } x4 := aStructure{123, 3.14, "A Structure"} st4 := reflect.ValueOf(&x4).Elem() typeOfX4 := st4.Type() fmt.Printf("X4 Type: %s\n", typeOfX4) fmt.Printf("The fields of %s are:\n", typeOfX4) for i := 0; i < st4.NumField(); i++ { fmt.Printf("%d: Field name: %s ", i, typeOfX4.Field(i).Name) fmt.Printf("Type: %s ", st4.Field(i).Type()) fmt.Printf("and Value: %v\n", st4.Field(i).Interface()) } }
Executing reflection.go prints the following output:
$ go run reflection.go X1 Type: main.t1 X2 Type: main.t2 X3 Type: int X4 Type: main.aStructure The fields of main.aStructure are: 0: Field name: X Type: uint and Value: 123 1: Field name: Y Type: float64 and Value: 3.14 2: Field name: Text Type: string and Value: A Structure
The first two lines of the output show that Go does not consider the types t1 and t2 as equal, even though both t1 and t2 are aliases of the int type.
Old habits die hard!
Despite the fact that Go tries to be a safe programming language, sometimes it is forced to forget about safety and allows the programmer to do whatever he/she wants.