### 尽我所能减少代码量的一种方式
这些方法都可以用于支持函数式编程的编程语言。
嗯,介绍的话都写在**注释**里了,光这些花费的时间就挺多的。就不重新排版了。
介绍下go的函数写法:
func [绑定类型]函数名 (形参列表)返回值/(返回列表){函数体}
简单点用法和其他语言一样
func 函数名(形参列表)返回值 {函数体}
```go
package main
import "fmt"
import "strconv"
func main() {
powerful(1, 2, NameFun4)
powerful(2, 3, NameFun5)
}
//下面6个函数不过是为了等下说明写的,在真实环境中可能不需要自己写
//六个函数4种不同的函数原型1、2,3、4,5,6 注意逗顿号
func fun1(i, j int) int {
return i + j
}
func fun2(i, j int) int {
return i - j
}
func fun3(i, j int) string {
return strconv.Itoa(i + j)
}
func fun4(i, j int) string {
return strconv.Itoa(i - j)
}
func fun5(i int) {
fmt.Println("this is out from fun4,i =",i)
}
func fun6() {
fmt.Println("this is fun6")
}
//这个函数在内部调用了fun1函数
func somefun1(i, j int) {
fmt.Println(fun1(i, j))
}
//这个函数内部调用fun2函数。。。有木有感觉和上面的重复了
//有木有感觉到很不爽
//其实现在还感觉不出什么不爽的,当这两个函数中代码量多时
//就会非常不爽,因为全是重复的代码
func somefun2(i, j int) {
fmt.Println(fun2(i, j))
}
type Fun12 func(i, j int) int
//用回调的方式就可以组合上面的代码了
//但是这也有问题。。。。。 万一对于fun1和fun2有一两步骤处理不一样
//比如接下来两个函数
//这时候如果在使用回调的话 哈哈哈 不同的部分该怎么写呢?
//如果还是用回调的话,我是没想到解决的方式
//不过我使用了一个不同的解决策略
func somefun12(i, j int, fun12 Fun12) {
fmt.Println(fun12(i, j))
}
//在调用fun1前写i自加
func func1(i, j int) {
i++
fmt.Println(fun1(i, j))
}
//调用fun2前自减
func func2(i, j int) {
i--
fmt.Println(fun2(i, j))
}
//在string基础上建立一个类型
//在c中就是别名,在go中有些不一样,但是这里不使用不相同的功能
type FuncName string
//常量初始化
const (
NameFun1 FuncName = "fun1"
NameFun2 FuncName = "fun2"
NameFun3 FuncName = "fun3"
NameFun4 FuncName = "fun4"
NameFun5 FuncName = "fun5"
NameFun6 FuncName = "fun6"
)
//可能有觉得这不是增加代码量了么
//嗯。。。。 真是环境中用下就知道是减少还是增加了
//不知道大家有木有觉得这又有一点不好之处
//嗯。。。哈哈哈。。虽然我已经把完美主义这个毛病改掉了
//但是强迫症还是有的
//我前面写了很多不同函数原型的函数,
//而下面函数的写法只适用于相同函数签名的情况下
//所以,嘿嘿,你懂的 我tm又想出了一个新的解决方法
func somefunc12(i, j int, funcName FuncName) {
//这个根据情况放函数外or里
funcs := map[FuncName] Fun12 {
NameFun1: fun1,
NameFun2: fun2,
}
if funcName == NameFun1 {
i++
}else if funcName == NameFun2 {
i--
}
fmt.Println(funcs[funcName](i, j))
}
type Fun34 func(i, j int) string
//嗯。。。突然单个函数的代码两上去了,可是这会让我们少写很多函数了
//所以从大的方面看 还是可以大大的减少代码量
//其实这还是有问题的。。。
//我感觉wtm是真tm的难以满足 。。。害羞.jpg
//这个函数的函数接口是固定的,但是当我们传入fun5和fun6函数的时候
//i和j其实很可能是不需要的
//其实还是有办法解决的,我在纠结要不要在这里写出解决方案
//其实也容易想到 用interface{}作为不定参数类型
//详细参照各语言的打印函数源码
//嗯。。。其实有些细节还可以优化下
//比如可以适当纠结西map的位置问题
//介绍完毕
func powerful(i, j int, funcName FuncName) {
//interface{}类型相当于java的object
funcs := map[FuncName] interface{} {
NameFun1: fun1,
NameFun2: fun2,
NameFun3: fun3,
NameFun4: fun4,
NameFun5: fun5,
NameFun6: fun6,
}
//不同函数不同处理方式就不写了,反正上面写过了
switch fun := funcs[funcName].(type) {
case Fun12:
fmt.Println(fun(i, j) + 1)
case Fun34:
fmt.Println(fun(i, j))
case func(i int):
fun(i)
fun(j)
case func():
fun()
}
}
```
有疑问加站长微信联系(非本文作者))