说我在Ruby中有这两个lambdas:
lambda1 = -> { puts 'lambda1' }
lambda2 = -> {
puts 'lambda2 calls lambda1'
lambda1.()
}
Run Code Online (Sandbox Code Playgroud)
它按预期工作:
lambda1.()
# lambda1
lambda2.()
# lambda2 calls lambda1
# lambda1
Run Code Online (Sandbox Code Playgroud)
但是现在如果我删除lambda1,lambda2将停止工作:
lambda1 = nil
lambda2.()
Run Code Online (Sandbox Code Playgroud)
NoMethodError:nil的未定义方法`call':NilClass
我能做些什么,以"胶水"我lambda1来lambda2,使第一,第二的固有部分,避免这种情况?
问题是你在一个闭包中lambda2捕获变量lambda1,因此它会在lambda1以后更改时注意到.解决方案只是让它捕获一个不同的变量:
lambda1 = -> { puts 'lambda1' }
x = lambda1 # copy the reference
lambda2 = -> { x.() }
lambda1 = nil
lambda2.()
Run Code Online (Sandbox Code Playgroud)
"但这也有同样的问题!" 你可能会说,"我可以通过重新分配来打破它x!" 好吧,然后使它x受范围保护:
def wrap x
-> { x.() }
end
lambda1 = -> { puts 'lambda1' }
lambda2 = wrap lambda1
lambda1 = nil
lambda2.()
Run Code Online (Sandbox Code Playgroud)