Значение списка не меняется при добавлении элементов в каждый блок - PullRequest
0 голосов
/ 24 мая 2018

У меня есть пустой список

val = []

Когда запускается приведенный ниже код

Enum.each [1, 2, 3], fn x ->
  IO.puts x
end

Мы получаем следующий вывод.

1
2
3
:ok

Это означает,элементы могут быть доступны в каждом блоке.

Теперь, когда я запускаю следующий код:

Enum.each [1, 2, 3], fn x ->
  IO.puts x
  val = val ++ [x]
end

Это дает следующий результат

1
2
3
:ok

Нозначение val не изменилось, оно по-прежнему равно [].

Если я запускаю отдельно iex

val = val ++ [1]

Значение val изменяется на [1].

Я новичок в эликсире с опытом работы в рубине.Необходимо понять причину, лежащую в основе вышеупомянутого поведения.

1 Ответ

0 голосов
/ 24 мая 2018

Это проблема с областью видимости.Будущие версии Elixir могут даже выдавать предупреждение, если вы попытаетесь перепривязать внешнюю переменную внутри внутренней области видимости (эта переменная отскока немедленно отбрасывается при оставлении области действия), в которой говорится, что приведенный выше код трижды перепривязывает внешнюю [] к[i] и впоследствии эффективно отбрасывает его.

Для достижения того, что вы хотите, используйте любой редуктор, например Enum.reduce/3:

Enum.reduce [1, 2, 3], [], fn x, val ->
  IO.puts x
  val ++ [x] # returning an accumulator
end
#⇒ 1
#  2
#  3

#⇒ [1, 2, 3]

Sidenote: в Ruby также считается запахом кода для утечки переменной аккумулятора из области видимости и / или областей смешивания:

# BAD
val = []
[1, 2, 3].each(&val.method(:<<))

# GOOD
val = [1, 2, 3].reduce([]) { |acc, e| acc << e }
...