- 前言
- Go 与操作系统
- Go 内部机制
- Go 基本数据类型
- 4 组合类型的使用
- 5 数据结构
- 6 Go package 中不为人知的知识
- 7 反射和接口
- 8 Go UNIX 系统编程
- 08.1 关于 UNIX 进程
- 08.2 flag 包
- 8.2 flag 包
- 08.3 io.Reader 和 io.Writer 接口
- 08.4 bufio 包
- 08.5 读取文本文件
- 08.6 从文件中读取所需的数据量
- 08.7 为什么我们使用二进制格式
- 08.8 读取 CSV 文件
- 08.9 写入文件
- 08.10 从磁盘加载和保存数据
- 08.11 再看strings包
- 08.12 关于bytes包
- 08.13 文件权限
- 08.14 处理 Unix 信号
- 08.15 Unix 管道编程
- 08.16 遍历目录树
- 08.17 使用 ePBF
- 08.18 关于 syscall.PtraceRegs
- 08.19 跟踪系统调用
- 08.20 User ID 和 group ID
- 08.21 其他资源
- 08.22 练习
- 08.23 总结
- 9 并发 Goroutines、Channel 和 Pipeline
- 10 Go 并发-进阶讨论
- 11 代码测试、优化及分析
- 12 Go 网络编程基础
- 13 网络编程 - 构建服务器与客户端
07.5.2 反射进阶
在本节中,我们将探讨反射的更高级的用法,将使用相对较小的 advRefl.go
的Go代码进行演示。
advRefl.go
程序将分五部分介绍。代码的第一部分如下:
package main import ( "fmt" "os" "reflect" ) type t1 int type t2 int
可以注意到尽管 t1
和 t2
类型都基于 int
类型,因此本质上也与 int
类型相同,但Go语言将它们视为完全不同的类型。它们在Go编译器解析后的内部表示分别是 main.t1
和 main.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
,因为 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()` 等。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论