今天给大家说一说关于go语言方法重载的方法,具体如下:
首先认清重载函数的定义
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://如果不为string或int
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
}
}