Abh*_*k S 4 functional-programming list-comprehension elixir
我是 Elixir 和函数式编程的新手,有 OO 背景。
我一直试图理解 Elixir 中列表理解中的变量重新分配是如何工作的。我期望函数 test1() 和 test2() 打印 4,但 test2() 不会重新分配变量并打印 1。
defmodule SampleCode do
def test1 do
num = 1
num = num + 1
num = num + 2
IO.puts num # Prints 4
end
def test2 do
num = 1
for i <- (1..2) do
num = num + i
end
IO.puts num # Prints 1
end
end
Run Code Online (Sandbox Code Playgroud)
这是 Elixir 中的变量作用域还是我所缺少的函数式编程的基本原则?
实际上两者都是。
Elixir 只允许在相同作用域和所有构造中重新绑定,但case、cond和除外receive,引入新的作用域。一些例子:
num = 1
try do
num = 2
after
num = 3
end
num #=> 1
Run Code Online (Sandbox Code Playgroud)
乐趣:
num = 1
(fn -> num = 2 end).()
num #=> 1
Run Code Online (Sandbox Code Playgroud)
现在举一些规则例外的例子:
num = 1
case true do
true -> num = 2
end
num #=> 2
num = 1
cond do
true -> num = 2
end
num #=> 2
Run Code Online (Sandbox Code Playgroud)
尽管如此,上述情况有些不鼓励,因为最好显式返回值:
num = 1
case x do
true -> 2
false -> num
end
#=> will return 1 or 2
Run Code Online (Sandbox Code Playgroud)
上面的示例明确了从 case 返回的值是什么。为什么 Elixir 中支持这些,尽管不推荐,这是一个很长的故事,它起源于 Erlang,并由于 Elixir 中的一些(很少)命令式宏而继续存在,例如if和unless。随着我们迈向 Elixir 2.0,它可能会发生变化。
执行您想要的操作的最佳方法是通过 中的函数Enum。您的特定示例可以用它来完成Enum.sum/1,但任何其他复杂的示例都可以用它来实现Enum.reduce/3(枚举中的几乎所有函数都是用reduce 来实现的,这可能会在其他语言中折叠)。