在go语言中,type可以定义任何自定义的类型
比如熟悉的:type dog struct{},type myInt int 等等
所以func也是可以作为类型自定义的,type myFunc func(int) int,意思是自定义了一个叫myFunc的函数类型,这个函数的签名必须符合输入为int,输出为int
已知,相同底层类型的变量之间是可以相互转换的,例如从一个取值范围小的int16转为取值范围大的int32
所以,自定义的 myInt 和 int 之间也是可以转换的
type myInt int func main() { var a int a = 2 b := myInt(a) fmt.Println(b) // 2 }
同理,myFunc 也是可以将签名为 func(int) int 的函数转换成 myFunc 类型
type myFunc func(int) int func sum10(num int) int { fmt.Println(num*10) } func main() { newFunc := myFunc(sum10) }
此时newFunc是一个变量,变量类型为myFunc,值为sum10函数!!!
那么,这个变量有什么用?
回过头来想想,自定义的类型有什么用?有什么场景需要自己定义一个myInt出来?就是重载原来的int类型,并自定义新的方法
type myInt int func (mi myInt) IsZero() bool { return mi == 0 } func main() { var a myInt a = 0 fmt.Println(a.IsZero()) // true }
同理,自定义函数类型也可以自定义方法
type myFunc func(int) int func (mf myfunc) sum(a,b int) int { c := a + b return mf(c) }
一个自定义函数类型的变量拥有了一个sum函数,有什么实际用途?
重点来了,有什么用途?
举个例子
type myFunc func(int) int func (f myFunc) sum (a, b int) int { res := a + b return f(res) } func sum10(num int) int { return num * 10 } func sum100(num int) int { return num * 100 } func handlerSum(handler myFunc, a, b int) int { res := handler.sum(a, b) fmt.Println(res) return res } func main() { newFunc1 := myFunc(sum10) newFunc2 := myFunc(sum100) handlerSum(newFunc1, 1, 1) // 20 handlerSum(newFunc2, 1, 1) // 200 }
解释下,假如handlerSum是一种特殊的sum算法,但是又有一部分的计算是可以通过外部自定义函数来干预的,那么使用这种方式就很合适
再进一步,如何使得handlerSum函数更抽象化?我必须传递一个myFunc类型的变量参数进来吗?参数是一个interface呢,一个拥有sum方法的interface是不是更通用?
type sumable interface { sum(int, int) int } // myFunc继承sumable接口 type myFunc func(int) int func (f myFunc) sum (a, b int) int { res := a + b return f(res) } func sum10(num int) int { return num * 10 } func sum100(num int) int { return num * 100 } // icansum结构体继承sumable接口 type icansum struct { name string res int } func (ics *icansum) sum(a, b int) int { ics.res = a + b return ics.res } // handler只要是继承了sumable接口的任何变量都行,我只需要你提供sum函数就好 func handlerSum(handler sumable, a, b int) int { res := handler.sum(a, b) fmt.Println(res) return res } func main() { newFunc1 := myFunc(sum10) newFunc2 := myFunc(sum100) handlerSum(newFunc1, 1, 1) // 20 handlerSum(newFunc2, 1, 1) // 200 ics := &icansum{"I can sum", 0} handlerSum(ics, 1, 1) // 2 }
这样handlerSum接受的是一个只要实现了sum接口的变量就可以了,可以是一个struct变量,也可以是一个自定义函数类型变量,只要变量继承实现了sum函数即可,这样就可以更自由的干预(自定义)handlerSum函数需要的执行过程了
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233955.html原文链接:https://javaforall.net