返回介绍

07.5.2 反射进阶

发布于 2024-08-14 12:50:32 字数 6305 浏览 0 评论 0 收藏 0

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

advRefl.go 程序将分五部分介绍。代码的第一部分如下:

package main

import (
    "fmt"
    "os"
    "reflect"
)

type t1 int
type t2 int

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

advRefl.go 的第二个代码部分如下:

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代码来执行其任务。

advRefl.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)
    }
}

printMethods() 函数用来打印一个变量的方法。在代码 advRefl.go 中用于说明 printMethods() 功能的变量类型是 os.File

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

advRefl.go 的最后一个代码部分如下:

    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 ,因为 a1a2 变量的值不同。

执行 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()` 等。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文