为什么变量没有在这个灵丹妙药无限流中反弹?

时间:2015-09-27 19:14:08

标签: elixir

我有以下内容:

counter = 0

try do
  for _ <- Stream.cycle([:ok]) do
    IO.puts "Counter is #{counter}"
    counter = counter + 1
    IO.puts "After counter: #{counter}"

    if counter == 3 do
      throw :halt
    end
  end
catch
  :halt -> IO.puts "Finished processing"
end

根据我的阅读,我认为counter = counter + 1将重新绑定变量,最终counter == 3条件将成立。但是,我得到的输出是这样的:

Counter is 0
After counter: 1
Counter is 0
After counter: 1
Counter is 0
...

所以,基本上,计数器会回到初始值。感觉就像for中的重新绑定工作就像局部变量一样,或者影响第一个变量。我怎样才能使值保持不变(如果可能的话没有递归)?

1 个答案:

答案 0 :(得分:2)

回答标题问题:它没有被重新绑定,因为do块通常*不能改变其范围之外的变量。您的IO语句表明它可以改变范围内的变量;但是当do块再次运行时,它会再次在新范围内运行,其中初始值是从原始值设置的。

回答内心问题:这取决于你想要做什么。您的示例无法深入了解您选择Stream模块超过Enum的原因。实现目标的一种方法是假设你知道要进行三次迭代是为了理解:

for i <- (1..3) do
  IO.inspect i
end

我可能会过度解释你的问题,我当然不是故意侮辱,但你似乎厌恶递归。如果你计划在Elixir中编写大量代码,那么你将需要克服这个问题 - 这是一种函数式语言,其中递归是惯用的 - 在任何语言中,使用语言编写都会提高效率而不是试图围绕你不熟悉的部分进行编码。

*例外情况,请参阅macro programming