Elixir 结构真的是不可变的吗?
Are Elixir structs really immutable?
我目前正在学习 Elixir,我正在阅读“使用 Elixir、OTP 和 Phoenix 进行功能性 Web 开发”,我认为这是一本很棒的书。
在状态机章节工作,我想出了以下代码:
defmodule IslandsEngine.Rules do
alias __MODULE__
defstruct state: :initialized
def new(), do: %Rules{}
def check(%Rules{state: :initialized} = rules, :add_player), do:
{:ok, %Rules{rules | state: :players_set}}
def check(_state, _action), do: :error
end
上面的代码应该作为功能齐全的状态机工作。
我将在上面粘贴一些 iex 命令:
iex(1)> alias IslandsEngine.Rules
IslandsEngine.Rules
iex(2)> rules = Rules.new()
%IslandsEngine.Rules{state: :initialized}
iex(3)> {:ok, rules} = Rules.check(rules, :add_player)
{:ok, %IslandsEngine.Rules{state: :players_set}}
iex(4)> rules.state
:players_set
正如您所见,状态结构已从 :initialized
更改为 :add_player
。太好了。
我的问题是:state:
结构真的不可变吗?我的意思是,方法 check/1
returns 带有 state: :players_set
语句的结构副本,它遵循正确的功能模式......但是它如何 "overwrite" 当前状态不直接修改?
非常感谢!
Elixir 数据结构确实是不可变的。但是发生的是 函数调用 return 一个全新的值 (根据您调用的函数,它与原始值不同)。
至于"changing the variable's value",Elixir
中的that's an added feature(超过原来的Erlang
语言)。变量的值实际上并没有改变,它只是重新绑定到新的值。旧的由 Erlang VM.
自动垃圾收集
所以在你的例子中:
# This returns a completely new `%Rules{}` struct and rebinds
# the `rules` variable to the new term
{:ok, rules} = Rules.check(rules, :add_player)
我目前正在学习 Elixir,我正在阅读“使用 Elixir、OTP 和 Phoenix 进行功能性 Web 开发”,我认为这是一本很棒的书。 在状态机章节工作,我想出了以下代码:
defmodule IslandsEngine.Rules do
alias __MODULE__
defstruct state: :initialized
def new(), do: %Rules{}
def check(%Rules{state: :initialized} = rules, :add_player), do:
{:ok, %Rules{rules | state: :players_set}}
def check(_state, _action), do: :error
end
上面的代码应该作为功能齐全的状态机工作。 我将在上面粘贴一些 iex 命令:
iex(1)> alias IslandsEngine.Rules
IslandsEngine.Rules
iex(2)> rules = Rules.new()
%IslandsEngine.Rules{state: :initialized}
iex(3)> {:ok, rules} = Rules.check(rules, :add_player)
{:ok, %IslandsEngine.Rules{state: :players_set}}
iex(4)> rules.state
:players_set
正如您所见,状态结构已从 :initialized
更改为 :add_player
。太好了。
我的问题是:state:
结构真的不可变吗?我的意思是,方法 check/1
returns 带有 state: :players_set
语句的结构副本,它遵循正确的功能模式......但是它如何 "overwrite" 当前状态不直接修改?
非常感谢!
Elixir 数据结构确实是不可变的。但是发生的是 函数调用 return 一个全新的值 (根据您调用的函数,它与原始值不同)。
至于"changing the variable's value",Elixir
中的that's an added feature(超过原来的Erlang
语言)。变量的值实际上并没有改变,它只是重新绑定到新的值。旧的由 Erlang VM.
所以在你的例子中:
# This returns a completely new `%Rules{}` struct and rebinds
# the `rules` variable to the new term
{:ok, rules} = Rules.check(rules, :add_player)