
很多编程语言都闭包的概念,最常见闭包使用的应该是 JavaScript 了。其实闭包不是什么新奇的概念,就是函数与函数特定环境的组合,闭包使用了本函数之外定义的变量。Golang 中也有所谓的闭包,本文对Golang中的闭包的概念中的关键点通过实际示例进行个简单的说明。
示例1package mainfunc add(base int) func(int) int { return func(i int) int { base += i return base }}func main() { tmp1 := add(10) fmt.Println(tmp(1),tmp(2)) tmp2 := add(100) fmt.Println(tmp2(1),tmp2(2))}
结果:
11 13101 103示例2
下面是个稍微复杂点的例子
func calc(base int) (func(int) int,func(int) int) { add := func(i int) int { base += i return base } sub := func(i int) int { base -= i return base } return add,sub } func main() { f1,f2 := calc(10) fmt.Println(f1(1),f2(2)) fmt.Println(f1(3),f2(4)) fmt.Println(f1(5),f2(6)) fmt.Println(f1(7),f2(8))}
结果
11 912 813 714 6示例3
涉及 goroutine 时的情况
package mainimport ( "fmt" "time")func main() { for i:=0; i<5; i++ { go func(){ fmt.Println(i) }() } time.Sleep(time.Second)}
结果:
55555
通过这三个示例的结果,我们可以了解到闭包中绑定的是外层函数中的变量本身,不是变量当时的值。也就是说闭包中绑定变量的值可以不断变化。但是要注意函数的不同执行会产生不同的闭包,这些闭包之间的变量不是共享,因为函数的每次执行都会重新生成新的局部变量,使得闭包每次绑定的变量不同。
闭包引起的问题最初使用 goroutine 的时候,曾遇到一个程序死锁的问题。思来想去看代码都觉得问题,最后发现是错误使用闭包导致的问题。
具体代码就不贴了,问题原型如下:
package mainimport "fmt"func main() { cs := make([](chan int), 10) for i := 0; i < len(cs); i++ { cs[i] = make(chan int) } for i := range cs { go func() { cs[i] <- i }() } for i := 0; i < len(cs); i++ { t := <-cs[i] fmt.Println(t) }}
出问题的就是这个地方
for i := range cs { go func() { cs[i] <- i }()}
由于goroutine还没有开始,i的值已经跑到了最大9,使得这几个goroutine都取的i=9这个值,从而都向cs[9]发消息,导致执行t := <-cs[i]时,cs[0]、cs[1]、cs[2] … 都阻塞起来了,从而导致了死锁。知道原因,改起来就容易了。
如下:
for i := range cs { go func(index int) { cs[index] <- index }(i)}总结
以上是内存溢出为你收集整理的Golang 闭包全部内容,希望文章能够帮你解决Golang 闭包所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)