如何使用变量中的键更新 Elixir 结构

Mik*_*iet 2 elixir

我有一些结构定义

defmodule Foo do
  defstruct [:a, :b]
end
Run Code Online (Sandbox Code Playgroud)

我有一些结构

a = %Foo{a: 1, b: 2}
Run Code Online (Sandbox Code Playgroud)

我能够使用管道(如地图)获得新的结构

%Foo{a | b: 3}
%Foo{a: 1, b: 3}
Run Code Online (Sandbox Code Playgroud)

但与 map 不同的是,当变量中的键时,我无法获取新结构:

iex(4)> key = :b
:b
iex(5)> %Foo{a | key => 3}
** (CompileError) iex:5: unknown key key for struct Foo
Run Code Online (Sandbox Code Playgroud)

问题:当我有更新变量的密钥时如何获得新结构?

Ada*_*hip 6

结构提供编译时检查数据的键是否限制为您指定的值。出于这个原因,不可能使用具有结构语义的动态键,因为键的值仅在运行时才知道。

您可以更新数据,但必须使用地图语义并放弃编译时检查:

%{foo | key => "bar"}
Run Code Online (Sandbox Code Playgroud)

或者

Map.replace!(foo, key, "bar")
Run Code Online (Sandbox Code Playgroud)

如果key无效,这些将给您一个运行时错误。

这就是为什么在使用结构体时最好在编译时尽可能使用结构体语义来指定键。