Ruby 大家对于在 for 循环中创建闭包的问题有什么解决方法没?

ptmagic · 2012年12月15日 · 最后由 googya 回复于 2012年12月15日 · 2938 次阅读

在 ruby 中闭包的创建所用的对象不能包含数组索引,这个怎么办呢?

irb(main):032:0> def a
irb(main):033:1> act = [] irb(main):034:1> for i in (0..5) do irb(main):035:2* act<<(Proc.new{|x| q=i; q**x}) irb(main):036:2> end irb(main):037:1> return act irb(main):038:1> end

irb(main):001:0> def a irb(main):002:1> act = [] irb(main):003:1> for i in (0..5) do irb(main):004:2* act<<(lambda{|x| i**x}) irb(main):005:2> end irb(main):006:1> return act irb(main):007:1> end

结果都是一样的。 在 python 中你可以这么设定闭包

def makeActions(): acts = [] for i in range(5): acts.append(lambda x, i=i: i ** x) return acts

Use defaults instead

Remember current i

acts = makeActions() # 0 ** 2 acts0 acts2 # 2 ** 2 acts4 # 4 ** 2

我想知道 ruby 中有没有这样的实现方式?

def a
  Array.new(6) do |i|
    lambda {|x| i**x }
  end
end
(0...5).map{|i| lambda{|x| i**x } }

你的问题在于错误使用了 for 循环,ruby 中的 for 不是代码块,因此 i 这个变量没有被隔离。实际上,ruby 中通常不需要使用 for 关键字,大部分情况下使用内部迭代的 api 就可以了

def a
   act = []
   [1,2,3,4,5].each do |i| 
      act << (Proc.new{|x|  i ** x}) 
   end 
   act 
end

用 for i in (1..5) 这种方式是不行的,因为 Proc 绑定的变量是 i,而 i 最后就变成了 5,导致数组中各 proc 都一样了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号