这种时候怎么实现?我只能觉得用类模拟指针了……

2014-03-30 22:09:30 +08:00
 tioover
不小心发出来了,我在回复里面说
4392 次点击
所在节点    Python
28 条回复
rannnn
2014-03-31 07:31:54 +08:00
PO主是在写解释器还是写lisp->py的编译器?
aristotle9
2014-03-31 11:11:33 +08:00
"但是 bar() 这个闭包函数是一个独立的,不应该依赖于 foobar() 的环境,不然只要 bar 存在,foobar 就不能被回收。"

这个说法不太对. 函数bar()依赖定义他的环境(词法作用域), 包括foobar的环境. foobar()可以回收, 但是他的环境还是会被引用到(如果bar()或者其他定义在其中的函数没有回收的话), 函数对环境的引用是单向的. 当所有引用某个环境的函数都被回收后, 该环境才会回收. 所以在设计上, 环境与函数是独立的, 可以把任意一个函数拿到任意一个环境中去求值.
环境的结构是一个map: ENV = {parent: ENV(上一层), data: {foo: 1,...}}

PO主可以去看看 ECMA-262或者http://www.eopl3.com/
exch4nge
2014-03-31 13:20:42 +08:00
额,回不回收的我不大懂。

def foobar():
....foo = 1
....def bar():
........return foo
....foo = 2

(话说如果bar被调用的话正确返回应该是2对吧……)
这时候foobar的context里是有变量foo的。 getContext(foobar) --> { foo: ?? }
建立bar的context的时候,bar的context只知道自己的context的parent是foobar的context。
getContext(bar).parent === getContext(foobar)

不管怎样,bar被调用的时候,肯定是在foobar函数里面所被调用的,调用的时候,foobar的context中的foo的变量是带着某个值的。然后bar里面出现foo,先从自己的context找foo变量,没有就继续递归往上找,直到找到一个,如果没找到就报错。

额,可能重点是lz的 “但是 bar() 这个闭包函数是一个独立的,不应该依赖于 foobar() 的环境”。这句话应该是不正确的吧……
exch4nge
2014-03-31 13:26:43 +08:00
补充一下。另外一个重点是遇到bar的定义的时候,不应该把foo的值传进去当作bar的context的。foo一直是foobar的context里面的变量
exch4nge
2014-03-31 13:44:16 +08:00
……没法删评论,好吧,我上面的理解是错的,大家请无视……

闭包是包含foo这样的东西的……
tioover
2014-03-31 14:36:52 +08:00
@exch4nge

def foobar():
....foo = 1
....def bar():
........return foo
....foo = 2
....return bar()
可以这样搞……
tioover
2014-03-31 14:37:15 +08:00
@exch4nge

def foobar():
....foo = 1
....def bar():
........return foo
....foo = 2
....return bar
上面的说错了……
gladuo
2018-10-27 14:59:39 +08:00
想想不能手动控制传值传引用是很蛋疼。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/106558

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX