闭包中引用循环变量的问题

来源:互联网 发布:大数据商务拓展怎么做 编辑:程序博客网 时间:2024/04/30 16:16

今天在看Go的语法,突然想对比一下python和Go的闭包机制的区别。

假如闭包调用循环变量,在Go中的实现方法为,循环中用一个新的变量保存这个循环变量的值,具体实现代码如下:

//Gopackage mainimport ("fmt""reflect")func main() {var funcArray = count()for index := range funcArray {funcArray[index]()}}func count() []func() {var a = make([]func(), 3)for index := range a {indexCopy := indexa[index] = func() {fmt.Println(indexCopy)}}return a}

三次循环中产生了三个新的indexCopy的量,于是这个程序最后打印出0, 1, 2.

但是在python中,必须这样实现:

#pythondef count():    l = []    for i in range(3):        def f(i):            def g():                return i            return g        l.append(f(i))    return lf1, f2, f3 = count()print f1()print f2()print f3()

先构造一个函数f(i)把i的值固定住,加入list中,实现引用循环变量的功能。

这时候问题来了,为什么python不能像go一样,新建一个循环变量的拷贝,像下面这样呢:

#pythondef count():    l = []    for i in range(3):        v = i        def f(i):            return v        l.append(f(i))    return l
这是python gc决定的。在for的三次循环中,变量v的地址是不变的,只是每次循环分别指向了常量区不同的常量。所以到了最后三个闭包函数所保存的v地址是一样的,而且都指向了常量区中的2,而Go中则是三个闭包函数保存着三个indexCopy变量的地址。

0 0
原创粉丝点击