- 前言
- 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.1 使用反射的简单示例
本节将介绍一个相对简单的反射示例,以便开始熟悉这个高级的Go语言功能。
示例的Go程序的名称是 reflection.go
,将分四部分介绍。 reflection.go
的目的是检查“未知类型”的结构变量,并在运行时了解更多有关它的信息。为了加深理解,程序将定义两个新的 struct
类型。基于这两种类型,它还将定义两个新变量;但是,示例程序只检查其中一个。如果程序没有命令行参数,它将检查第一个参数;否则,它将探索第二个。实际上,这意味着程序不会预先知道它将要处理的 struct
变量的类型。
reflection.go
的第一部分包含以下Go代码:
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
数据类型的定义。
reflection.go
的第二个代码段如下:
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)` 。
reflection.go
的第三个部分包含以下Go代码:
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` )中包含的值。
reflection.go
代码的最后一部分如下:
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```类型。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论