滁州网站建设梦天堂,个人主页页面设计制作,wordpress 栏目调用,网页游戏排行榜前十微信小程序Golang 进阶5—— 反射
注意#xff0c;该文档只适合有编程基础的同学#xff0c;这里的go教程只给出有区别的知识点
反射#xff1a;
反射可以在运行时动态获取变量的各种信息#xff0c; 比如变量的类型、 类别等信息。如果是结构体变量#xff0c;还可以获取结构体本…Golang 进阶5—— 反射
注意该文档只适合有编程基础的同学这里的go教程只给出有区别的知识点
反射
反射可以在运行时动态获取变量的各种信息 比如变量的类型、 类别等信息。如果是结构体变量还可以获取结构体本身的信息结构体的字段、方法。通过反射 可以修改变量的值可以调用关联的方法。使用反射 需要import(“reflect”)
1.1 main函数
package mainimport (fmtreflect
)// 利用一个函数 函数的参数定义为空接口
// 空接口没有任何方法所以可以理解为所有类型都实现了空接口
// 也可以理解为我们可以把任何一种类型赋值给空接口
func testReflect (data interface{}) {// 1、 调用 TypeOf函数 返回reflect.Type 类型的数据fmt.Println(data type is , reflect.TypeOf(data))// 2、 调用 ValueOf函数 返回reflect.Value 类型的数据reVal : reflect.ValueOf(data)fmt.Println(data value is , reVal)// 3、 如果要获取具体类型的值 可以调用 Int 方法sum : 100 reVal.Int()fmt.Println(sum is , sum)// 4、 reVal 转成空接口i2 : reVal.Interface()fmt.Println(i2 is , i2)// 5、类型断言n : i2.(int)n2 : n 200fmt.Println(n2 is , n2)fmt.Println(i2 type is , reflect.TypeOf(i2))
}1.2 输出结果
(base) PS E:\Goproject\src\gocode\testproject03 go run .\main\main.go
data type is int
data value is 10
sum is 110
i2 is 10
n2 is 210
i2 type is int1.3 结构体情况
import (fmtreflect
)type Student struct {Name stringAge int
}// 利用一个函数 函数的参数定义为空接口
// 空接口没有任何方法所以可以理解为所有类型都实现了空接口
// 也可以理解为我们可以把任何一种类型赋值给空接口
func testReflect (data interface{}) {// 1、 调用 TypeOf函数 返回reflect.Type 类型的数据fmt.Println(data type is , reflect.TypeOf(data))// 2、 调用 ValueOf函数 返回reflect.Value 类型的数据reVal : reflect.ValueOf(data)fmt.Println(data value is , reVal)// 3、 reVal 转成空接口i2 : reVal.Interface()fmt.Println(i2 is , i2)if s, ok : i2.(Student); ok {fmt.Println(i2 is student:, s.Name)} else {fmt.Println(i2 is not a student)}
}func main () {stu1 : Student{xiaoxiao, 18}testReflect(stu1)
}1.4 输出结果
(base) PS E:\Goproject\src\gocode\testproject03 go run .\main\main.go
data type is main.Student
data value is {xiaoxiao 18}
i2 is {xiaoxiao 18}
i2 is student: xiaoxiao1.5 获取变量类别
import (fmtreflect
)type Student struct {Name stringAge int
}// 利用一个函数 函数的参数定义为空接口
// 空接口没有任何方法所以可以理解为所有类型都实现了空接口
// 也可以理解为我们可以把任何一种类型赋值给空接口
func testReflect (data interface{}) {// 1、 调用 TypeOf函数 返回reflect.Type 类型的数据reType : reflect.TypeOf(data)fmt.Println(data type is , reType)// 2、 调用 ValueOf函数 返回reflect.Value 类型的数据reVal : reflect.ValueOf(data)fmt.Println(data value is , reVal)// 3、 获取变量的类别大范围k1 : reVal.Kind()fmt.Println(data kind is , k1)k2 : reType.Kind()fmt.Println(data kind is , k2)// 4、 获取变量的类型 小范围i2 : reVal.Interface()if n, ok : i2.(Student); ok {fmt.Println(n is , n)} else {fmt.Println(n is not Student)}}func main () {stu1 : Student{xiaoxiao, 18}testReflect(stu1)
}1.6 输出结果
(base) PS E:\Goproject\src\gocode\testproject03 go run .\main\main.go
data type is main.Student
data value is {xiaoxiao 18}
data kind is struct
data kind is struct
n is {xiaoxiao 18}1.7 对结构体操作
// 1. 定义结构体
type Student struct {Name stringAge int
}// 2. 给结构体绑定方法
func (stu Student) Print() {fmt.Print(调用了Print方法)fmt.Println(stu)
}func (stu Student) GetSum(n1, n2 int) int {return n1 n2
}func (stu Student) Set(name string, age int) {stu.Name namestu.Age age
}func testReflect(data interface{}) {reVal : reflect.ValueOf(data)// 检查 data 是否是指针并获取指向的值if reVal.Kind() reflect.Ptr {reVal reVal.Elem()}fmt.Println(reVal)// 获取结构体中字段的数量n1 : reVal.NumField()fmt.Println(字段的数量, n1)for i : 0; i n1; i {// 输出字段fmt.Printf(字段 %d 的名字是 %s, 对应的值为 %v \n, i, reVal.Type().Field(i).Name, reVal.Field(i))}// 获取结构体的方法数量n2 : reVal.NumMethod()fmt.Println(方法的数量, n2)// 输出方法for i : 0; i n2; i {// 输出方法fmt.Printf(方法 %d 的名字是 %s \n, i, reVal.Type().Method(i).Name)}// 调用方法, 调用的方法首字母必须大写reVal.MethodByName(Print).Call(nil)// 调用GetSum方法// 定义Value切片var params []reflect.Valueparams append(params, reflect.ValueOf(10))params append(params, reflect.ValueOf(20))sum : reVal.MethodByName(GetSum).Call(params)fmt.Println(sum , sum[0])
}func main() {stu : Student{Name: Tom, Age: 18}testReflect(stu) // 传入 stu 的指针
}1.8 输出结果
(base) PS E:\Goproject\src\gocode\testproject03 go run .\main\main.go
{Tom 18}
字段的数量 2
字段 0 的名字是 Name, 对应的值为 Tom
字段 1 的名字是 Age, 对应的值为 18
方法的数量 3
方法 0 的名字是 GetSum
方法 1 的名字是 Print
方法 2 的名字是 Set
调用了Print方法{Tom 18}
sum 301.9 改值
import (fmtreflect
)// 1. 定义结构体
type Student struct {Name stringAge int
}// 2. 给结构体绑定方法
func (stu Student) Print() {fmt.Print(调用了Print方法)fmt.Println(stu)
}func (stu Student) GetSum(n1, n2 int) int {return n1 n2
}func (stu Student) Set(name string, age int) {stu.Name namestu.Age age
}func testReflect(data interface{}) {reVal : reflect.ValueOf(data)// 通过setInt方法修改值n : reVal.Elem().NumField()fmt.Println(结构体中字段个数为, n)reVal.Elem().Field(0).SetString(Jack)reVal.Elem().Field(1).SetInt(30)
}func main() {stu : Student{Name: Tom, Age: 18}testReflect(stu) // 传入 stu 的指针fmt.Println(stu)
}1.10 输出结果
(base) PS E:\Goproject\src\gocode\testproject03 go run .\main\main.go
结构体中字段个数为 2
{Jack 30}