反射的基本使用
一 反射的使用场景——JSON序列化
1 代码
package main
import (
"encoding/json"
"fmt"
)
type Monster struct {
Name string `json:"monsterName"` // `json:"name"` 就是 struct tag
Age int `json:"monsterAge"`
Sal float64 `json:"monsterSal"`
Sex string `json:"monsterSex"`
}
func main() {
m := Monster{
Name: "玉兔精",
Age: 20,
Sal: 888.76,
Sex: "female",
}
data, _ := json.Marshal(m)
fmt.Println("json result", string(data))
}
2 测试
json result {“monsterName”:”玉兔精”,”monsterAge”:20,”monsterSal”:888.76,”monsterSex”:”female”}
3 分析
为什么序列化后,key-val 的 key 值是结构体 Tag 的值,而不是字段的名称。比如,不是 Name,而是 monsterName。这是因为底层使用到了反射。
二 反射的使用场景——函数的适配器和桥连接
1 代码
package main
import "fmt"
func main() {
// 定义一个匿名函数
test1 := func(v1 int, v2 int) {
fmt.Println(v1, v2)
}
// 定义另外一个匿名函数
test2 := func(v1 int, v2 int, s string) {
fmt.Println(v1, v2, s)
}
// 定义一个适配器函数,统一处理接口
bridge := func(call interface{}, args ...interface{}) {
fmt.Println("内容")
}
// 实现调用 test1 对应的函数
bridge(test1, 1, 2)
// 实现调用 test2 对应的函数
bridge(test2, 1, 2, "求和")
}
2 测试
内容
内容
3 分析
该适配器使用底层使用的便是反射
三 反射的基本介绍
1 基本介绍
a 反射可以在运行时动态获取变量的各种信息, 比如变量的类型(type),类别(kind)。
b 如果是结构体变量,还可以获取到结构体本身的信息:包括结构体的字段、 方法。
c 通过反射,可以修改变量的值,可以调用关联的方法。
d 使用反射,需要 import(“reflect”)
e 示意图
2 反射的应用场景
a 不知道接口调用哪个函数,根据传入参数在运行时确定调用的具体接口,这种需要对函数和方法反射。例如下面这种桥接模式。
func bridge(funcPtr interface{}, args …interface{})
第1个参数 funcPtr 以接口的形式传入函数指针,函数参数 args 以可变参数的形式传入,bridge 函数中可以用反射来动态执行 funcPtr 函数。
b 对结构体序列化时,如果结构体有指定 Tag,也会使用到反射生成对应的字符串。
package main
import (
"encoding/json"
"fmt"
)
type Monster struct {
Name string `json:"monsterName"` // `json:"name"` 就是 struct tag
Age int `json:"monsterAge"`
Sal float64 `json:"monsterSal"`
Sex string `json:"monsterSex"`
}
func main() {
m := Monster{
Name: "玉兔精",
Age: 20,
Sal: 888.76,
Sex: "female",
}
data, _ := json.Marshal(m)
fmt.Println("json result", string(data))
}
3 反射重要的函数和概念
a reflect.Type(变量名),获取变量的类型,返回 reflect.Type 类型。
b reflect.ValueOf(变量名),获取变量的值,返回 reflex.Value 类型。reflex.Value 是一个结构体类型,通过 reflex.Value 类型,可以获取到关于该变量的很多信息。
c 变量、interface{} 和 reflect.Value 是可以相互转换的,这点在实际开发中,会经常使用到。示意图如下。
还没有评论,来说两句吧...