探究Go类型参数的函数

Go语言中,函数的定义与函数的调用方可以不一致。换句话说,缺乏runtime类型安全就允许函数调用端的参数与函数定义端的参数不一致。Go不支持函数的多态特性,这就决定了无法根据参数的类型或者个数定义多态的函数。但是,可以定义多态参数。Go构建函数中,append, close, delete, copy, cap 和 len函数都使用了参数多态。

Go编程中,有时候为了达到代码的简洁美而编写一些泛化的函数。这些泛化的函数利用就是Go反射机制。

/**
目标函数模型为:
func CallTypeFunc(f func(A) B, ps []A) []B
 */
 //Only support Go 1.1以上的发布版本
func CallTypeFunc(f interface{}, ps interface{}) interface{} {
    vf := reflect.ValueOf(f)
    vps := reflect.ValueOf(ps)

    // 3) Map's return type must be `[]B1` where `B == B1`.
    tys := reflect.SliceOf(vf.Type().Out(0))

    vys := reflect.MakeSlice(tys, vps.Len(), vps.Len())
    for i := 0; i < vps.Len(); i++ {
        y := vf.Call([]reflect.Value{vps.Index(i)})[0]
        vys.Index(i).Set(y)
    }
    return vys.Interface()
}

第一个函数的输入参数与第二个参数切片的类型相同,参数函数的返回类型与整个函数的返回类型相同,即泛化的模型为:func CallTypeFunc(f func(A) B, ps []A) []B

验证上面的函数,测试代码见下文。

fmt.Printf(" CallTypeFunc(func(x string) int { return len(x) }, []string{\"1\", \"10\", \"100\"}).([]int) return :%+v",
    CallTypeFunc(func(x string) int { return len(x) }, []string{"1", "10", "100"}))

fmt.Printf(" CallTypeFunc(func(x int) int { return x*x }, []int{1, 10, 100}).([]int) return :%+v",
    CallTypeFunc(func(x int) int { return x*x }, []int{1, 10, 100}))

//输出结果:
// CallTypeFunc(func(x string) int { return len(x) }, []string{"1", "10", "100"}).([]int) return :[1 2 3]
//CallTypeFunc(func(x int) int { return x*x }, []int{1, 10, 100}).([]int) return :[1 100 10000]

认真分析上面的代码,你会发现参数有bug。没有验证输入参数类型是否符合函数的参数定义。为了修复这个问题,需要加上参数验证逻辑。

待续下篇文章!

欢迎加入我的微信公众号

欢迎加入我的微信公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值