0

当我有以下方法时:

def n_times(thing)
  lambda { |n| thing * n }
end

我这样称呼它:

x  = [:a]
p1 = n_times(x)
x  = [:b]
p p1.call(3) # => [:a, :a, :a]

x 不会改变,输出将是 [:a]。为什么?

当做类似 .pop 的事情时, x 将被改变:

x  = [:a]
p1 = n_times(x)
x.pop
p p1.call(3) # => []

是因为 [:b] 是一个新对象吗?

4

2 回答 2

1

是因为 [:b] 是一个新对象吗?

是的。当您这样做时x.pop,您正在修改xthing引用的对象。当你这样做时x = [:b],你会x引用一个新对象。使变量引用新对象不会影响其他变量或对象。

请注意,如果 lambda 关闭了 variable x,那将是另一回事。在这种情况下,更改x会影响 lambda,但事实并非如此。lambda 关闭了 variable thing,这是一个不同的变量,在重新分配之前只是碰巧引用了同一个对象x

于 2013-09-28T09:36:20.960 回答
1

这是因为x在第一种情况下分配了一个新对象。您可以通过检查来检查object_id

x  = [:a]
p x.object_id # =>  //some number
p1 = n_times(x)
x  = [:b]  
p x.object_id  # => //diff number
p p1.call(3) # => [:a, :a, :a] 

x  = [:a]
p x.object_id # =>  //some number
p1 = n_times(x)
x.pop
p x.object_id # => //same number
p p1.call(3) # => []

# Another example
x  = [:a]
p x.object_id # =>  //some number
p1 = n_times(x)
x[0]  = :b 
p x.object_id # => //same number
p p1.call(3) # => [:b, :b, :b]
于 2013-09-28T09:39:32.763 回答