2016-05-17 67 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更新 –

相關問題