使用反射的简单示例

本节将介绍一个相对简单的反射示例,以便开始熟悉这个高级的Go语言功能。

示例的Go程序的名称是reflection.go,将分四部分介绍。reflection.go的目的是检查“未知类型”的结构变量,并在运行时了解更多有关它的信息。为了加深理解,程序将定义两个新的struct类型。基于这两种类型,它还将定义两个新变量;但是,示例程序只检查其中一个。如果程序没有命令行参数,它将检查第一个参数;否则,它将探索第二个。实际上,这意味着程序不会预先知道它将要处理的struct变量的类型。

  1. >

package main

import ( “fmt” “os” “reflect” )

type a struct { X int Y float64 Z string }

type b struct { F int G int H string I float64 } ```

在程序的这一部分中,您可以看到将要使用的struct数据类型的定义。

  1. >

func main() { x := 100 xRefl := reflect.ValueOf(&x).Elem() xType := xRefl.Type() fmt.Printf(“The type of x is %s.\n”, xType) ```

上面的Go代码提供了一个小的、简单的反射示例。首先声明一个名为x的变量,然后调用reflect.ValueOf(&x).Elem()函数。接下来调用xRefl.Type()以获取存储在xType中的变量类型。这三行代码说明了如何使用反射获取变量的数据类型。如果只关心变量的数据类型,那么可以改为调用reflect.TypeOf(x)

  1. >
  1. A := a{100, 200.12, "Struct a"}
  2. B := b{1, 2, "Struct b", -1.2}
  3. var r reflect.Value
  4. arguments := os.Args
  5. if len(arguments) == 1 {
  6. r = reflect.ValueOf(&A).Elem()
  7. } else {
  8. r = reflect.ValueOf(&B).Elem()
  9. }

```

在本部分中,声明了两个名为AB的变量。A变量的类型为aB变量的类型为br变量的类型定义为reflect.Value,因为这是函数reflect.ValueOf()返回的结果。Elem()方法返回反射接口(reflect.Value)中包含的值。

  1. >
  1. iType := r.Type()
  2. fmt.Printf("i Type: %s\n", iType)
  3. fmt.Printf("The %d fields of %s are:\n", r.NumField(), iType)
  4. for i := 0; i < r.NumField(); i++ {
  5. fmt.Printf("Field name: %s ", iType.Field(i).Name)
  6. fmt.Printf("with type: %s ", r.Field(i).Type())
  7. fmt.Printf("and value %v\n", r.Field(i).Interface())
  8. }

} ```

在程序的这一部分中,使用了reflect包中适当的功能来获取所需的信息。NumField()方法返回reflect.Value结构中的字段个数,而Field()函数返回结构中的指定字段。Interface()函数的作用是以接口类型,返回reflect.Value结构字段的值。

两次执行reflection.go将得到以下输出:

  1. $ go run reflection.go 1
  2. The type of x is int.
  3. i Type: main.b
  4. The 4 fields of main.b are:
  5. Field name: F with type: int and value 1
  6. Field name: G with type: int and value 2
  7. Field name: H with type: string and value Struct b
  8. Field name: I with type: float64 and value -1.2
  9. $ go run reflection.go
  10. The type of x is int.
  11. i Type: main.a
  12. The 3 fields of main.a are:
  13. Field name: X with type: int and value 100
  14. Field name: Y with type: float64 and value 200.12
  15. Field name: Z with type: string and value Struct a

值得注意的是我们看到Go使用其内部表示来打印变量AB的数据类型,分别是main.amain.b。但是,变量x不是这样的,它是系统内置的int类型。