reflection.go
,将分四部分介绍。reflection.go
的目的是检查“未知类型”的结构变量,并在运行时了解更多有关它的信息。为了加深理解,程序将定义两个新的struct
类型。基于这两种类型,它还将定义两个新变量;但是,示例程序只检查其中一个。如果程序没有命令行参数,它将检查第一个参数;否则,它将探索第二个。实际上,这意味着程序不会预先知道它将要处理的struct
变量的类型。package mainimport ( "fmt" "os" "reflect" )type a struct { X int Y float64 Z string }type b struct { F int G int H string I float64 } ```
struct
数据类型的定义。func main() { x := 100 xRefl := reflect.ValueOf(&x).Elem() xType := xRefl.Type() fmt.Printf("The type of x is %s.\n", xType) ```
x
的变量,然后调用reflect.ValueOf(&x).Elem()
函数。接下来调用xRefl.Type()
以获取存储在xType
中的变量类型。这三行代码说明了如何使用反射获取变量的数据类型。如果只关心变量的数据类型,那么可以改为调用reflect.TypeOf(x)
。A := a{100, 200.12, "Struct a"} B := b{1, 2, "Struct b", -1.2} var r reflect.Value1arguments := os.Args2if len(arguments) == 1 {3r = reflect.ValueOf(&A).Elem()4} else {5r = reflect.ValueOf(&B).Elem()6}Copied!```
A
和B
的变量。A
变量的类型为a
,B
变量的类型为b
。r
变量的类型定义为reflect.Value
,因为这是函数reflect.ValueOf()
返回的结果。Elem()
方法返回反射接口(reflect.Value
)中包含的值。iType := r.Type() fmt.Printf("i Type: %s\n", iType) fmt.Printf("The %d fields of %s are:\n", r.NumField(), iType)1for i := 0; i < r.NumField(); i++ {2fmt.Printf("Field name: %s ", iType.Field(i).Name)3fmt.Printf("with type: %s ", r.Field(i).Type())4fmt.Printf("and value %v\n", r.Field(i).Interface())5}Copied!} ```
reflect
包中适当的功能来获取所需的信息。NumField()
方法返回reflect.Value
结构中的字段个数,而Field()
函数返回结构中的指定字段。Interface()
函数的作用是以接口类型,返回reflect.Value
结构字段的值。reflection.go
将得到以下输出:1$ go run reflection.go 12The type of x is int.3i Type: main.b4The 4 fields of main.b are:5Field name: F with type: int and value 16Field name: G with type: int and value 27Field name: H with type: string and value Struct b8Field name: I with type: float64 and value -1.29$ go run reflection.go10The type of x is int.11i Type: main.a12The 3 fields of main.a are:13Field name: X with type: int and value 10014Field name: Y with type: float64 and value 200.1215Field name: Z with type: string and value Struct aCopied!
A
和B
的数据类型,分别是main.a
和main.b
。但是,变量x
不是这样的,它是系统内置的int
类型。