cat*_*ory 4 dictionary immutability elixir mutability gen-server
最近我解决了一个涉及更新大量关键值的问题.
当然,我考虑使用a 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}
Run Code Online (Sandbox Code Playgroud)
然后我握住的状态解决了这个问题Map的GenServer,以及使用更新它handle_cast/3的调用.
一般来说,这是正确的方法,还是这个太多了?
然后我握住的状态解决了这个问题
Map的GenServer[...]一般来说,这是正确的做法,还是这太多了吗?
这很大程度上取决于你的目标.存储状态有许多不同的方法.重新绑定变量如:
m = Map.put(%{}, :a, 1)
#? %{a: 1}
m = Map.put(m, :b, 2)
#? %{a: 1, b: 2}
Run Code Online (Sandbox Code Playgroud)
不存储任何东西.它将局部变量绑定m到RHO,并且一旦控制流离开范围,该变量就会变为垃圾收集.无论您是否需要在单一范围内提供上述地图,GenServer(和其他国家持有者)都是一种过度杀伤力.
OTOH,如果你需要长时间存储状态并在不同的范围之间共享(例如在不同的进程之间),这GenServer是实现这一目标的最简单方法.在Elixir中,我们有Agent模块来减少样板,因为GenServer它被用作简单的内存存储,但我的建议是永远使用GenServer:迟早Agent会变得太紧,不适合你的目的.
此外,可以使用ets模块来保持进程内共享的内存中键值存储.
dets是一种在进程重启之间存储状态的方法.
最后,mnesia是一种OTP本机方法,用于在重新启动和不同节点之间共享状态(在分布式环境中).