您的位置:首页 > 其它

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

2016-12-25 20:21 351 查看
今天在看Go的语法,突然想对比一下python和Go的闭包机制的区别。

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

//Go
package main

import (
"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 := index
a[index] = func() {
fmt.Println(indexCopy)
}
}
return a
}

三次循环中产生了三个新的indexCopy的量,于是这个程序最后打印出0, 1, 2.
但是在python中,必须这样实现:

#python

def count():
l = []
for i in range(3):
def f(i):
def g():
return i
return g
l.append(f(i))
return l

f1, f2, f3 = count()
print f1()
print f2()
print f3()

先构造一个函数f(i)把i的值固定住,加入list中,实现引用循环变量的功能。
这时候问题来了,为什么python不能像go一样,新建一个循环变量的拷贝,像下面这样呢:#python

def 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变量的地址。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: