> 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.2.md).

# 07.5.2 反射进阶

在本节中，我们将探讨反射的更高级的用法，将使用相对较小的`advRefl.go`的Go代码进行演示。

```
>
```

> package main
>
> import ( "fmt" "os" "reflect" )
>
> type t1 int type t2 int \`\`\`

可以注意到尽管`t1`和`t2`类型都基于`int`类型，因此本质上也与`int`类型相同，但Go语言将它们视为完全不同的类型。它们在Go编译器解析后的内部表示分别是`main.t1`和`main.t2`。

```
>
```

> type a struct { X int Y float64 Text string }
>
> func (a1 a) compareStruct(a2 a) bool { r1 := reflect.ValueOf(\&a1).Elem() r2 := reflect.ValueOf(\&a2).Elem()
>
> ```
> for i := 0; i < r1.NumField(); i++ {
>     if r1.Field(i).Interface() != r2.Field(i).Interface() {
>         return false
>     }
> }
> return true
> ```
>
> } \`\`\`

在这个代码段中，我们定义了一个名为`a`的Go结构类型，并实现了一个名为`compareStruct()`的Go函数。这个函数的目的是找出类型`a`的两个变量是否完全相同。如您所见，`compareStruct()`使用`reflection.go`中的Go代码来执行其任务。

```
>
```

> func printMethods(i interface{}) { r := reflect.ValueOf(i) t := r.Type() fmt.Printf("Type to examine: %s\n", t)
>
> ```
> for j := 0; j < r.NumMethod(); j++ {
>     m := r.Method(j).Type()
>     fmt.Println(t.Method(j).Name, "-->", m)
> }
> ```
>
> } \`\`\`

````
```advRefl.go```的第四段包含以下Go代码：

>
````

> func main() { x1 := t1(100) x2 := t2(100) fmt.Printf("The type of x1 is %s\n", reflect.TypeOf(x1)) fmt.Printf("The type of x2 is %s\n", reflect.TypeOf(x2))
>
> ```
> var p struct{}
> r := reflect.New(reflect.ValueOf(&p).Type()).Elem()
> fmt.Printf("The type of r is %s\n", reflect.TypeOf(r))
> ```
>
> \`\`\`

```
>
```

> a1 := a{1, 2.1, "A1"} a2 := a{1, -2, "A2"}
>
> ```
> if a1.compareStruct(a1) {
>     fmt.Println("Equal!")
> }
>
> if !a1.compareStruct(a2) {
>     fmt.Println("Not Equal!")
> }
>
> var f *os.File
> printMethods(f)
> ```
>
> } \`\`\`

正如您稍后将看到的，`a1.compareStruct(a1)`调用返回`true`，因为我们正在比较`a1`与自身，而`a1.compareStruct(a2)`调用将返回`false`，因为`a1`和`a2`变量的值不同。

执行`advRefl.go`将得到以下输出：

> ```
> $ go run advRefl.go
> The type of x1 is main.t1
> The type of x2 is main.t2
> The type of r is reflect.Value
> Equal!
> Not Equal!
> Type to examine: *os.File
> Chdir --> func() error
> Chmod --> func(os.FileMode) error
> Chown --> func(int, int) error
> Close --> func() error
> Fd --> func() uintptr
> Name --> func() string
> Read --> func([]uint8) (int, error)
> ReadAt --> func([]uint8, int64) (int, error)
> Readdir --> func(int) ([]os.FileInfo, error)
> Readdirnames --> func(int) ([]string, error)
> Seek --> func(int64, int) (int64, error)
> Stat --> func() (os.FileInfo, error)
> Sync --> func() error
> Truncate --> func(int64) error
> Write --> func([]uint8) (int, error)
> WriteAt --> func([]uint8, int64) (int, error)
> WriteString --> func(string) (int, error)
> ```

可以看到由`reflect.New()`返回的`r`变量的类型是`reflect.Value`。另外，`printMethods()`方法的输出可以看到`*os.File`类型支持很多的方法，例如：`Chdir()`、`Chmod()`等。
