Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dictionary 长生不老药中的储存状态_Dictionary_Elixir_Immutability_Gen Server_Mutability - Fatal编程技术网

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本机方法,用于在重启和不同节点(在分布式环境中)之间共享状态