【问题标题】:Are Elixir structs really immutable? [duplicate]Elixir 结构真的不可变吗? [复制]
【发布时间】:2019-04-06 02:05:45
【问题描述】:

我目前正在学习 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 方法返回带有 state: :players_set 语句的结构副本,该语句遵循正确的功能模式......但是它如何“覆盖”当前状态而不直接修改它?

非常感谢!

【问题讨论】:

标签: struct erlang elixir elixir-mix elixir-iex


【解决方案1】:

Elixir 数据结构确实是不可变的。但是发生的情况是 函数调用返回一个全新的值(根据您调用的函数,这与原始值不同)。

至于“改变变量的值”,that's an added feature in Elixir(在原来的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)

【讨论】:

    猜你喜欢
    • 2015-07-10
    • 1970-01-01
    • 2015-12-24
    • 2019-09-20
    • 1970-01-01
    • 2019-01-29
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多