有意思:Go 函数的闭包

用户头像
申屠鹏会
关注
发布于: 2020 年 08 月 12 日

“有意思”系列将会分享平时遇到的好玩的东西,不限于代码。

函数值

Go的函数也是值,可以像其他值一样进行传递。换句话说,就像int,string一样,可以用作函数的参数或者返回值。

来设计一个有意思的函数,假设我们要对两个数字3,4进行处理,比如对它们进行求和,求差,求积,就可以先定义一个模板函数deal,它接受一个处理函数作为参数,返回值就是处理完的结果:

func deal(fn func(n1, n2 int) int) int {
return fn(3, 4)
}

再定义一些处理函数:

func main() {
multiply := func(n1, n2 int) int { return n1 * n2 }
sum := func(n1, n2 int) int { return n1 + n2 }
differ := func(n1, n2 int) int { return n1 - n2 }
fmt.Println("两数乘积: ", deal(multiply))
fmt.Println("两数之和: ", deal(sum))
fmt.Println("两数之差: ", deal(differ))
}

multiply变量的值为乘法函数,接受n1,n2两个参数,返回n1和n2的积。同理,sum为两数之和的处理函数,differ为两数之差的处理函数。最后deal接受不同的处理函数作为入参,对3,4进行处理。结果如下

两数乘积: 12

两数之和: 7

两数之差: -1

函数的闭包

Go函数可以是一个闭包。闭包是一个函数值,它引用了其函数体之外的变量。该函数可以访问并赋予其引用的变量的值,换句话说,该函数被这些变量绑定在一起

比如我们要计算1 + 2 + 3 + ··· + n的值,除了公式法,让我们用函数闭包来做,首先定一个一个返回值是函数的函数:

func adder() func(int) int {
sum := 0
return func(i int) int {
sum += i
return sum
}
}

当 n = 100时:

func main() {
compute := adder()
for i := 0; i <= 100; i++ {
fmt.Println(compute(i))
}
}

最后,结果为5050.

斐波那契闭包

通常斐波那契函数0, 1, 1, 2, 3, 5,···可以用递归或者公式法做,那么如果是函数闭包呢?我们可以设计一个函数,每次调用返回一个数,第一次返回0,第二次返回1,第三次返回1,第四次返回2...没错,闭包就可以做这个事。

func fibonacci() func() int {
n1 := -1
n2 := 1
return func() int {
n1, n2 = n2, n1+n2
return n2
}
}

fibonacci()返回一个函数,该函数的值是返回经过计算的内部初始值的n2。运行一下:

func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}

运行结果0, 1, 1, 2, 3, 5, 8, 13, 21, 34

参考资料

A Tour of Go



发布于: 2020 年 08 月 12 日 阅读数: 29
用户头像

申屠鹏会

关注

enjoy~ 2018.11.08 加入

https://xabc.site

评论

发布
暂无评论
有意思:Go函数的闭包