官术网_书友最值得收藏!

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()) 
   } 
} 
There exist some laws that govern reflection in Go, but talking about them is beyond the scope of this book. What you should remember is that your programs can examine their own structure using reflection, which is a very powerful capability.

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.

主站蜘蛛池模板: 繁昌县| 青河县| 浦城县| 安丘市| 白城市| 武鸣县| 铁岭县| 雅安市| 中卫市| 泰安市| 台北县| 芜湖市| 道孚县| 都昌县| 宝兴县| 达日县| 晋江市| 乡城县| 商南县| 阿尔山市| 石泉县| 奎屯市| 宝清县| 左贡县| 临泽县| 宝兴县| 安乡县| 盐津县| 金沙县| 柳州市| 洞头县| 夹江县| 遵义市| 屏山县| 亳州市| 米脂县| 丹寨县| 安图县| 馆陶县| 玛沁县| 临海市|