Dictionary 长生不老药中的储存状态
最近,我解决了一个涉及更新大量键值的问题 当然,我考虑过使用Dictionary 长生不老药中的储存状态,dictionary,elixir,immutability,gen-server,mutability,Dictionary,Elixir,Immutability,Gen Server,Mutability,最近,我解决了一个涉及更新大量键值的问题 当然,我考虑过使用Map,使用类似Map.put/3的操作 然而,鉴于Elixir中数据结构的不变性质,这似乎是不够的: iex>m=Map.put(%{},:a,1) %{a:1} iex>Map.put(m,:b,2) %{a:1,b:2} iex>m %{a:1} 然后,我通过在GenServer中保持Map的状态,并使用handle\u cast/3调用对其进行更新,解决了这个问题 一般来说,这是正确的方法,还是太多了?你的第一种方法是正确的,
Map
,使用类似Map.put/3
的操作
然而,鉴于Elixir中数据结构的不变性质,这似乎是不够的:
iex>m=Map.put(%{},:a,1)
%{a:1}
iex>Map.put(m,:b,2)
%{a:1,b:2}
iex>m
%{a:1}
然后,我通过在GenServer
中保持Map
的状态,并使用handle\u cast/3
调用对其进行更新,解决了这个问题
一般来说,这是正确的方法,还是太多了?你的第一种方法是正确的,你只是错了一件事 更新映射时应重新绑定变量,如下所示:
iex> m = Map.put(%{}, :a, 1)
%{a: 1}
iex> m = Map.put(m, :b, 2)
%{a: 1, b: 2}
iex> m
%{a: 1, b: 2}
但你必须明白,它不会变异变量,它会创建一个新的映射并将其重新绑定到同一个变量
现在,这种方法是最简单的,您必须将此映射传递给使用它的每个函数。作为另一种选择,您可以考虑使用<代码>代理> /Cult>模块。所有关于它的内容和用途的信息都可以在它的文档中找到
然后,我通过在GenServer
[…]中保持映射的状态来解决问题
总的来说,这是正确的方法,还是太多了
这在很大程度上取决于你的目标。有许多不同的方法来存储状态。重新绑定变量,如:
m = Map.put(%{}, :a, 1)
#⇒ %{a: 1}
m = Map.put(m, :b, 2)
#⇒ %{a: 1, b: 2}
不储存任何东西。它将局部变量m
绑定到RHO,一旦控制流离开作用域,该变量就会被垃圾回收。无论您是否需要在单个范围内使用上述映射,GenServer
(以及其他状态持有者)都是一种过分的做法
OTOH,如果您需要长时间存储状态并在不同的作用域之间(例如,在不同的进程之间)共享它,GenServer
是实现这一点的最简单方法。在Elixir中,我们有一个模块来减少GenServer
的样板文件,该文件用作简单的内存存储,但我的建议是始终使用GenServer
:迟早Agent
对于您的目的来说会变得太紧
此外,还可以使用模块在内存中保存键值存储,在进程之间共享
是一种在进程重新启动之间存储状态的方法
最后,是一种OTP本机方法,用于在重启和不同节点(在分布式环境中)之间共享状态