Struct 长生不老药结构真的是不可变的吗?

Struct 长生不老药结构真的是不可变的吗?,struct,erlang,elixir,elixir-mix,elixir-iex,Struct,Erlang,Elixir,Elixir Mix,Elixir Iex,我目前正在学习Elixir,我正在阅读《Elixir、OTP和Phoenix的功能性Web开发》,imo是一本很棒的书。 在“状态机”一章中,我提出了以下代码: defmodule IslandsEngine.Rules do alias __MODULE__ defstruct state: :initialized def new(), do: %Rules{} def check(%Rules{state: :initialized} = rules, :add_pl

我目前正在学习Elixir,我正在阅读《Elixir、OTP和Phoenix的功能性Web开发》,imo是一本很棒的书。 在“状态机”一章中,我提出了以下代码:

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:
struct真的是不可变的吗?我的意思是,方法
check/1
返回一个带有
state::players\u set
语句的结构副本,该语句遵循正确的函数模式。。。但是它如何在不直接修改的情况下“覆盖”当前状态呢


非常感谢

Elixir数据结构确实是不可变的。但实际情况是,函数调用返回一个全新的值(这与原始值不同,具体取决于调用的函数)

至于“更改变量值”,在
Elixir
中(在原始
Erlang
语言上)。变量的值实际上没有改变,只是重新绑定到新的变量。旧的垃圾由Erlang VM自动垃圾收集。


在你的例子中:

#返回一个全新的`%Rules{}`结构并重新绑定
#新术语的“rules”变量
{:好的,规则}=规则。检查(规则:添加球员)

刚刚意识到,有一个现有的问题和答案更详细地涵盖了这一点:另一个有趣的Q/A可能会澄清更多事情: