这是我在https://blog.codeship.com/statefulness-in-elixir/上看到的 Stack 示例的编辑版本(由 Micah Woods 提供)。顺便说一句,它有效。
defmodule Stack do
def start_link do
pid = spawn_link(__MODULE__, :loop, [[]])
{:ok, pid}
end
def loop(stack) do
receive do
{:size, sender} ->
send(sender, {:ok, Enum.count(stack)})
{:push, item} -> stack = [item | stack]
{:pop, sender} ->
[item | stack] = stack
send(sender, {:ok, item})
end
loop(stack)
end
end
在loop()
函数内部,stack
变量在某些情况下会在receive
块中反弹,但在其他情况下不会。这似乎是可变变量的行为,而不是变量重新绑定。
在我看来,只有在新旧变量之间有明确的界限时,才应该允许重新绑定变量。即只有当代码可以在没有变量重新绑定的情况下被重写。在没有变量重新绑定的语言中,loop()
代码如下所示:
def loop(stack) do
receive do
{:size, sender} ->
send(sender, {:ok, Enum.count(stack)})
###### stack2 not defined in this case ######
{:push, item} -> stack2 = [item | stack]
{:pop, sender} ->
[item | stack2] = stack
send(sender, {:ok, item})
end
loop(stack2)
end
注意stack2
在第一种情况下没有定义。如果没有发生赋值,那么默认情况下被赋值,还是stack2
实际上是一个可变变量?stack
stack
那么我如何正确和合乎逻辑地理解 Elixir 中的这个重新绑定概念呢?在我看来,这正在侵犯可变变量领域。重新绑定如何在引擎盖下工作?