> For the complete documentation index, see [llms.txt](https://wskdsgcf.gitbook.io/mastering-go-zh-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wskdsgcf.gitbook.io/mastering-go-zh-cn/7-fan-she-he-jie-kou/07.5/07.5.1.md).

# 07.5.1 使用反射的简单示例

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

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

```
>
```

> 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`数据类型的定义。

```
>
```

> 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)`。

```
>
```

> A := a{100, 200.12, "Struct a"} B := b{1, 2, "Struct b", -1.2} var r reflect.Value
>
> ```
> arguments := os.Args
> if len(arguments) == 1 {
>     r = reflect.ValueOf(&A).Elem()
> } else {
>     r = reflect.ValueOf(&B).Elem()
> }
> ```
>
> \`\`\`

在本部分中，声明了两个名为`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)
>
> ```
> for i := 0; i < r.NumField(); i++ {
>     fmt.Printf("Field name: %s ", iType.Field(i).Name)
>     fmt.Printf("with type: %s ", r.Field(i).Type())
>     fmt.Printf("and value %v\n", r.Field(i).Interface())
> }
> ```
>
> } \`\`\`

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

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

> ```
> $ go run reflection.go 1
> The type of x is int.
> i Type: main.b
> The 4 fields of main.b are:
> Field name: F with type: int and value 1
> Field name: G with type: int and value 2
> Field name: H with type: string and value Struct b
> Field name: I with type: float64 and value -1.2
> $ go run reflection.go
> The type of x is int.
> i Type: main.a
> The 3 fields of main.a are:
> Field name: X with type: int and value 100
> Field name: Y with type: float64 and value 200.12
> Field name: Z with type: string and value Struct a
> ```

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