小谈golang闭包

    一直用java没用过闭包(我还很菜,可能java也能闭包我不会罢了,希望有人回帖指点),刚接触golang对其闭包机制也挺疑惑。下面写了六个版本的闭包小谈一下。有几个版本摘自别家,看了有段时间我一时不记得来源了很对不起作者了!

版本1:

package main

import "fmt"

func main() {

	var fn [10]func()

	for i := 0; i < len(fn); i++ {
		fn[i] = func() {
			fmt.Println(i)
		}
	}
	
	for _, f := range fn {
		f()
	}
}
结果如下:
10
10
10
10
10
10
10
10
10
10

分析:mian()与func()[]数组构成闭包使用同一个i变量main函数不退出i变量一直存在,f()执行时调用打印语句此时变量i为10。

版本2:
package main

import "fmt"

func main() {
	
	var fn [10]func()
	
	for i := 0; i < len(fn); i++ {
		fn[i] = func() {
			fmt.Println(i)
		}
	}
	
	for i := 0 ; i < len(fn); i++ {
		fn[i]()
	}
}
结果如下:
10
10
10
10
10
10
10
10
10
10

分析:与版本1对比使用显示的i变量做为迭代,但是闭包空间中的i与调用迭代中的i指向内存不同(生存空间也不同)所以使用闭包空间中的i作为打印值为10。

版本3:
package main

import "fmt"

func main() {
	
	var fn [10]func()

	for i := 0; i < len(fn); i++ {
		fn[i] = func() {
			fmt.Println(i)
		}
	}
	
	for j := 0 ; j < len(fn); j++ {
		fn[j]()
	}
}
结果如下:
10
10
10
10
10
10
10
10
10
10

分析:为证明版本2中的分析说法,使用j作为迭代变量,同样打印的10.

版本4:
package main

import "fmt"

func main() {
	
	var fn [10]func()
	var i int
	
	for i = 0; i < len(fn); i++ {
		fn[i] = func() {
			fmt.Println(i)
		}
	}
	
	for i = 0; i < len(fn); i++ {
		fn[i]()
	}
}
结果如下:
0
1
2
3
4
5
6
7
8
9

分析:在main()中声明变量i此时i的生存空间扩大到了main()函数,两次迭代使用同一个i变量。故在第二次迭代时i的迭代当前值会作为打印参数。

版本5:

package main

import "fmt"

func main() {
	
	var fn [10]func()

	for i := 0; i < len(fn); i++ { 
		fn[i] = make_fn(i)
	}
	
	for _, f := range fn {
		f()
	}
}

func make_fn(i int) func() {
	return func() {
		fmt.Println(i)
	}
}
结果如下:
0
1
2
3
4
5
6
7
8
9

分析:在main()函数外定义单独的闭包函数,构成独立的闭包单元,隔离不同func()[]中不同的func()。隔离与独立才是闭包的意义所在,一个表示一系列状态的集合不该在外部为显示通知改变时改变其内部状态。

版本6:

package main

import "fmt"

func main() {
	
	var fn [10]func(int)

	for i := 0; i < len(fn); i++ { 
		fn[i] = make_fn()
	}
	
	for i, f := range fn {
		f(i)
	}
}

func make_fn() func(i int) {
	return func(i int) {
		fmt.Println(i)
	}
}
结果如下:
0
1
2
3
4
5
6
7
8
9

分析:最后这个版本应该为最佳,gotour中的闭包示例使用的正是此中表示方式。     

能力有限只能写这么多了,本人第一次发博支持一下,有意见直说谢谢(漫骂亦可)!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值