golang 反射 reflect
reflect 是 golang 的一个标准库, 通过反射可以获取变量的类型、值、tag 等,它是实现 gorm、json、yaml 等库的基础. golang 语言通过反射可以在运行时动态的调用对象的方法和属性.
源码结构
golang reflect 反射的源码位于 golang/go/src/reflect 中,目录下包含以下文件
- type.go
- value.go
- swapper.go
- deepequal.go
- makefunc.go
- all_test.go
- asm_s390x.s
- example_test.go
- set_test.go
- export_test.go
- tostring_test.go
- asm_amd64p32.s
- asm_mips64x.s
- asm_386.s
- asm_arm.s
- asm_mipsx.s
- asm_wasm.s
- asm_amd64.s
- asm_arm64.s
- asm_ppc64x.s
在源码中, .s 是一些 golang 汇编文件,核心代码 type.go 3155 行代码, value.go 包含 2774 行代码,swapper.go 及 deepequal.go makefunc.go 总计 309 行代码,剩余 go test 源码 7536 余行.
可以看到 reflect 库的核心源码仅 6000 余行, 对这些代码的理解, 有助于更深刻的理解 golang 的 struct 及一些优秀框架、模块的实现原理.
golang struct
相比与其它语言, golang 的 struct 中可以在类型后增加一段字符串, 即 Tag,在编写程序时,常常通过如下形式对数据进行解析等处理,比如下图所示:
type jsonStruct struct {
A int `json:"a,omitempty"`
}
上面的 struct 中, 变量包含 value、type 及 tag, 其中 tag 内的成员标签变量时 key、value 健值对形式的,参考 StructTag.Lookup(key string) 中获取 tag 中指定 key 的方法
通过 json.Unmarshal 可以将 json 字符串解析到 jsonStruct 类型对象中,同样可以将该类型对象格式化为 json 字符串. 而 json.Unmarshal 及 json.Marshal 都是通过 reflect 实现的.
基础库 reflect
反射是用