2015-09-27 15 views
2

我有以下几点:为什么变量不会在这个灵药无限流中被反弹?

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内部的rebinding像局部变量一样工作,或者阴影第一个。我怎样才能让这个值保持不变(如果可能的话,没有递归)?

回答

2

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

要回答内在的问题:这取决于你想要做什么。你的例子并没有透露你为什么选择Stream模块而不是Enum。一种方式来实现自己的目标,假设你知道有是三次迭代是一个用于理解:

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

我可能是过度解读你的问题,我当然不意味着是侮辱性的,但你似乎厌恶递归。如果您打算在Elixir中编写大量代码,那么您需要完成这项工作 - 这是一种函数式语言,其中递归是惯用的 - 在任何语言中,编写这种语言比试图编写代码更有效率你不熟悉的部分。

*例外,见macro programming

+0

感谢您的回答!我不喜欢递归,我只是好奇是否有其他方式退出循环时满足条件,而不必使用递归。 – Geo

相关问题