3.2 KiB
3.2 KiB
一 反射的使用
1.1 反射操作简单数据类型
var num int64 = 100
// 设置值:指针传递
ptrValue := reflect.ValueOf(&num)
newValue := ptrValue.Elem() // Elem()用于获取原始值的反射对象
fmt.Println("type:", newValue.Type()) // int64
fmt.Println(" can set:", newValue.CanSet()) // true
newValue.SetInt(200)
// 获取值:值传递
rValue := reflect.ValueOf(num)
fmt.Println(rValue.Int()) // 方式一:200
fmt.Println(rValue.Interface().(int64)) // 方式二:200
1.2 反射进行类型推断
type user struct {
Name string
Age int
}
u := &user{
Name: "Ruyue",
Age: 100,
}
fmt.Println(reflect.TypeOf(u)) // *main.user
fmt.Println(reflect.TypeOf(*u)) // main.user
fmt.Println(reflect.TypeOf(*u).Name()) // user
fmt.Println(reflect.TypeOf(*u).Kind()) // struct
1.3 反射操作指针
type user struct {
Name string
Age int
}
u := &user{
Name: "Ruyue",
Age: 100,
}
typeOfUser = reflect.TypeOf(u).Elem()
fmt.Println("element name: ", typeOfUser.Name()) // user
fmt.Println("element kind: ", typeOfUser.Kind()) // struct
1.4 反射操作结构体
反射可以获取结构体的详细信息:
type user struct {
Name string
Age int `json:"age" id:"100"` // 结构体标签
}
s := user{
Name: "zs",
Age: 1,
}
typeOfUser := reflect.TypeOf(s)
// 字段用法
for i := 0; i < typeOfUser.NumField(); i++ { // NumField 当前结构体有多少个字段
fieldType := typeOfUser.Field(i) // 获取每个字段
fmt.Println(fieldType.Name, fieldType.Tag)
}
if userAge, ok := typeOfUser.FieldByName("Age"); ok {
fmt.Println(userAge) // {Age int json:"age" id:"100" 16 [1] false}
}
// 方法用法
for i := 0; i < typeOfUser.NumMethod(); i++ {
fieldType := typeOfUser.Method(i) // 获取每个字段
fmt.Println(fieldType.Name)
}
二 反射调用函数与方法
2.1 使用反射调用函数
如果反射值对象(reflect.Value)中值的类型为函数时,可以通过 reflect.Value调用该 函数。使用反射调用函数时,需要将参数使用反射值对象的切片 口reflect.Value 构造后传入 Call()方法中 , 调用完成时,函数的返回值通过 []reflect.Value 返回 。
func add(name string, age int) {
fmt.Printf("name is %s, age is %d \n", name, age)
}
func main() {
funcValue := reflect.ValueOf(add)
params := []reflect.Value{reflect.ValueOf("lisi"), reflect.ValueOf(20)}
reList := funcValue.Call(params)
fmt.Println(reList) // 函数返回值
}
2.2 反射调用方法
方法的调用是需要接收者的:
package main
import (
"fmt"
"reflect"
)
type user struct {
Name string
Age int
}
func (u *user) ShowName() {
fmt.Println(u.Name)
}
func (u *user) AddAge(addNum int) {
fmt.Println("age add result:", u.Age + addNum)
}
func main() {
u := &user{"lisi", 20}
v := reflect.ValueOf(u)
// 调用无参方法
methodV := v.MethodByName("ShowName")
methodV.Call(nil) // 或者传递一个空切片也可
// 调用有参方法
methodV2 := v.MethodByName("AddAge")
args := []reflect.Value{reflect.ValueOf(30)} //
methodV2.Call(args)
}