[go 反射] 函数

编程入门 行业动态 更新时间:2024-10-26 13:36:31

[go <a href=https://www.elefans.com/category/jswz/34/1765951.html style=反射] 函数"/>

[go 反射] 函数

[go 反射] 函数

go 函数反射的基础认识

  • 输入参数
  • 返回输出

输入参数和输出

NumIn()此方法属于reflect.Type接口,用于获取参数数量;In(int)用于获取对应位置的参数
NumOut()此方法属于reflect.Type接口,用于获取返回变量的数量;Out(int)用于获取对应位置的返回变量

演示

var one func(string,int,bool)inttp:=reflect.TypeOf(one)
fmt.Println(tp.NumIn(),tp.NumOut())
//从左到右依次输出输入参数的变量基础类型
for i:=0;i<tp.NumIn();i++{fmt.Println(tp.In(i).Kind())
}
//依次输出返回变量的基础类型
for i:=0;i<tp.NumOut();i++{fmt.Println(tp.Out(i).Kind())
}

反射运行函数

Call([]reflect.Value)[]relfect.Value属于reflect.Value结构体的方法,运行此方法即可达到调用函数的目的,参数通过反射过后放入数组内给call

演示

func Greet(name string)string{fmt.Println("call greet function")return "hello "+name
}
func main(){tp:=reflect.TypeOf(Greet)vl:=reflect.ValueOf(Greet)input:="jim"fmt.Println(tp.NumIn(),tp.NumOut())//两者都是1ans:=vl.Call([]reflect.Value{reflect.ValueOf(input)})reflect.ValueOf(&input).Elem().Set(ans[0])//将结果替换掉原来的inputfmt.Println(input)
}

终极实现——任意函数调用接口

//能够通过此方法调用任意现存函数,并返回到结构体
func AnyFunc[T any](src any, dst *T, args ...any) (err error) {stp, dtp := reflect.TypeOf(src), reflect.TypeOf(dst).Elem()svl, dvl := reflect.ValueOf(src), reflect.ValueOf(dst).Elem()if svl.IsNil() || stp.Kind() != reflect.Func {err = str_error("src function invaild")return}if stp.NumIn() != len(args) {err = str_error("args can't match the function args")return}var argsvl []reflect.Value = make([]reflect.Value, len(args))for i, ele := range args {argsvl[i] = reflect.ValueOf(ele)}outvl := svl.Call(argsvl)outcount := stp.NumOut()if dst == nil && outcount > 0 {err = str_error("dst is null")return}if outcount == 1 {if dtp == outvl[0].Type() {if dvl.CanSet() {dvl.Set(outvl[0])} else {err = str_error("dst can't be set")}} else {err = str_error("dst type is don't match")}} else if outcount > 1 {if dtp.Kind() == reflect.Struct {//结构体非严格匹配赋值,请看[go 反射] 结构体if dtp.NumField() >= outcount {var i, j = 0, 0var anspos []int = make([]int, 0, outcount)for i < dtp.NumField() && j < outcount {if dtp.Field(i).Type == outvl[j].Type() {if dvl.Field(i).CanSet() {anspos = append(anspos, i)}j++}i++}if len(anspos) == outcount {for key, pos := range anspos {dvl.Field(pos).Set(outvl[key])}} else {err = str_error("precheck failed")}} else {err = str_error("your recieve struct fields not enough")}} else if dtp.Kind() == reflect.Map {if dvl.IsNil() {dvl.Set(reflect.MakeMap(dtp))}} else {err = str_error("you should use struct pointer to recieve return ans")}}return
}

更多推荐

[go 反射] 函数

本文发布于:2023-11-16 17:19:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1628289.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:反射   函数

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!