2016-05-17 51 views
1

我试图在Enum.each函数中设置一个变量的值,但是在循环结束时,变量是空的,我不知道这个行为的原因。为什么Enum.each中设置的变量没有保存?

代码:

base = "master" 
candidates = ["stream", "pigeons", "maters"] 

return = [] 
Enum.each(candidates, fn candidate -> 
    cond do 
     String.length(base) == String.length(candidate) -> 
      return = return ++ [candidate] 
     true -> 
      true 
    end 
end) 
IO.inspect return 

在这个例子中,return预期为["stream", "maters"],而是,它只是一个空列表:[]

我的问题是为什么会这样。

回答

4

在处理Elixir等语言时,最好用“值”和“名称”来代替“变量”。

你不能做你想做的事的原因是Elixir有"lexical scoping"。 当您分配给“变量”时,将在内部范围中创建一个新值。您永远不会更改外部作用域中定义的“名称”的“值”。

(你也许可以得到你想要什么Enum.filter/2,但我猜这只是一个说明性的例子)

编辑:

截至今日,药剂会允许你写这样的事情:

if condition_that_evals_to_false do 
    x = 1 
else 
    x = 2 
end 

IO.inspect x # => 2 

```

但是,这将在花好月圆1.3

被弃用
0

不知道,因为我从来没有在语言的工作,但有两件事情映入脑海:

String.length(base) == String.length(candidate)可以等同于真实的,这已经是你的设置模式。

它也可能是返回变量的范围问题。可能是当地的回报隐藏了全球的回报。你可以通过输出每次迭代的返回来检查它。每次迭代返回都应包含一个条目。

+0

你是正确的关于本地价值是不同于全球。 –

4

任何你不只是过滤的原因?

无论如何,它似乎是你试图改变回报的价值,这是药剂不可能的。

base = "master" 
candidates = ["stream", "pigeon", "maters"] 
result = Enum.filter(candidates, fn(candidate) -> 
    length(candidate) == length(base) 
end 

IO.inspect result 

编辑:我还想补充一点,根据你的逻辑,所有的候选人将返回

+0

你对所有返回的信息都是正确的。我在这个例子中输入了错字,并且已经编辑过。 –

+0

关于你的逻辑,是的,它比我的好多了,谢谢! :) –

+0

我的问题是用你的逻辑解决的,但问题仍然需要回答。因此,我不能选择你的答案来解决问题。谢谢;) –

-1

这是一个错误。从Elixir's documentation

注:由于0.12.x系列中的错误,标准条件的条件实际上 泄漏绑定到周围的范围。这应该在 0.13.1中修复。

您应该使用@ {Christopher Yammine}建议的过滤方式。

+0

你大约晚了9个月。药剂目前在1.2.5 –

+0

嗯......这是隆隆的午睡。 Thx更新 –

相关问题