探究Go类型参数的函数 - Go语言中文社区

探究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。没有验证输入参数类型是否符合函数的参数定义。为了修复这个问题,需要加上参数验证逻辑。

待续下篇文章!

欢迎加入我的微信公众号

欢迎加入我的微信公众号

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/GreatElite/article/details/78854108
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2019-08-27 15:46:42
  • 阅读 ( 738 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢