# 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`类型。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wskdsgcf.gitbook.io/mastering-go-zh-cn/7-fan-she-he-jie-kou/07.5/07.5.1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
