Golang重载函数(反射模拟)

84 篇文章 3 订阅
  • 首先认清重载函数的定义
    1:函数参数个数不同
    2:函数参数类型不同,或者类型顺序不同
    Go语言本身不支持函数的重载,所以,我们利用反射+switch进行模拟反射,动态进行函数调用。

根据函数参数的个数不同,实现函数重载

首先声明结构体,并绑定两个参数

type Students struct {
	Name string `json:"name"`
	Age int
}
func (stu Students)T(n1 int,n2 int)int{//方法需要传递两个参数
	return n1+n2
}
func (stu Students)R(n1 int)int{//方法需要传递一个参数
	return n1
}

实现动态调用方法的函数

func reflecttest(n interface{},n2 ...interface{})(int,error){
	v:=reflect.ValueOf(n)
	switch len(n2) {
	case 1://如果传参为一个值
		params:=make([]reflect.Value,1)
		params[0]=reflect.ValueOf(n2[0])//注意传参时,需要将值的类型转化为value类型
		return int(v.MethodByName("R").Call(params)[0].Int()),nil//注意,返回的值以数组形式进行返回,再将返回的值转化为int64,再强制转化为int型数据
	case 2:如果参数为两个
		params:=make([]reflect.Value,2)
		for k,v1:=range n2{
			params[k]=reflect.ValueOf(v1)
		}
		return int(v.MethodByName("T").Call(params)[0].Int()),nil
	default://如果传参的数量不是一个或两个。
		err:=errors.New("调用函数不存在")
		return 0,err//返回错误
	}
}

根据函数参数类型的不同,调用不同的函数

结构体及其绑定的方法

type Students struct {
	Name string `json:"name"`
	Age int
}
func (stu Students)T(n1 int,n2 int)string{
	return n1+"T()"+strconv.Itoa(n2)
}
func (stu Students)R(n1 int,n2 string)string{
	return strconv.Itoa(n1)+"R()"+n2
}
func reflecttest(n interface{},n2 ...interface{})(string,error){
	v:=reflect.ValueOf(n)
	if len(n2)!=2{//如果参数个数不为2,返回错误
		err:=errors.New("参数个数错误")
		return "",err
	}
	if reflect.TypeOf(n2[0]).String()!="int"{//如果第一个数据类型不为int型,返回错误
		err:=errors.New("参数类型错误")
		return "",err
	}
	switch  n2[1].(type){//针对第二个参数的参数类型,进行讨论
	case string://如果为string
		params:=make([]reflect.Value,2)
		for k,v1:=range n2 {
			params[k]=reflect.ValueOf(v1)
		}
		return v.MethodByName("R").Call(params)[0].String(),nil
	case int://如果为int
		params:=make([]reflect.Value,2)
		for k,v1:=range n2{
			params[k]=reflect.ValueOf(v1)
		}
		return v.MethodByName("T").Call(params)[0].String(),nil
	default://如果不为stringint
		err:=errors.New("未找到相应函数")
		return "",err
	}
}

类型顺序不同,调用不同函数

结构体及其绑定的方法

type Students struct {
	Name string `json:"name"`
	Age int
}
func (stu Students)T(n1 string,n2 int)string{
	return n1+"T()"+strconv.Itoa(n2)
}
func (stu Students)R(n1 int,n2 string)string{
	return strconv.Itoa(n1)+"R()"+n2
}
func reflecttest(n interface{},n2 ...interface{})(string,error){
	if len(n2)!=2{//判断参数是否为2个
		err:=errors.New("参数个数不正确")
		return "",err
	}
	v:=reflect.ValueOf(n)
	params:=make([]reflect.Value,2)
	switch n2[0].(type) {
	case string://判断第一个参数的类型
		if reflect.TypeOf(n2[1]).String()=="int"{//判断第二个参数的类型
			for k,v1:=range n2{
				params[k]=reflect.ValueOf(v1)
			}
			return v.MethodByName("T").Call(params)[0].String(),nil
		}else{
			err:=errors.New("由于第二个参数类型错误,未能找到函数")
			return "",err
		}
	case int://判断第一个参数类型
		if reflect.TypeOf(n2[1]).String()=="string"{//判断第二个参数类型
			for k,v1:=range n2{
				params[k]=reflect.ValueOf(v1)
			}
			return v.MethodByName("R").Call(params)[0].String(),nil
		}else{
			err:=errors.New("第二个参数类型错误,函数调用失败")
			return "",err
	}
	default:
		err:=errors.New("第一个参数类型错误,函数调用失败")
		return "",err
	}
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值