GenServer 可以在 Elixir 中拥有自己的结构吗?
Can a GenServer Have Its Own Struct in Elixir?
场景:
- 我有一个简单的
GenServer
来管理一些状态。
- 目前,我正在使用
map
来管理我的状态。但它正在增长
我正在向状态添加更多数据。
问题:
- 那么,为了获得一些编译时保证,我可以在我的
GenServer
模块中有一个 struct
吗?
- 而且,如果是,这是正确的方法吗?
- 如果不行,还有哪些选择?
只需声明一个普通结构(可选地在嵌套在您的 GenServer
命名空间中的模块中)并将其用作初始状态:
defmodule Test do
defmodule State do
defstruct ~w|foo bar baz|a
end
use GenServer
def start_link(opts \ []) do
GenServer.start_link(__MODULE__, %State{foo: 42, bar: opts}, name: __MODULE__)
end
@impl true
def init(opts \ []), do: {:ok, opts}
def state, do: GenServer.call(__MODULE__, :state)
@impl true
def handle_call(:state, _from, %State{} = state) do
{:reply, state, state}
end
end
with {:ok, _} <- Test.start_link(pi: 3.14) do
IO.inspect Test.state, label: "State"
end
#⇒ State: %Test.State{bar: [pi: 3.14], baz: nil, foo: 42}
场景:
- 我有一个简单的
GenServer
来管理一些状态。 - 目前,我正在使用
map
来管理我的状态。但它正在增长 我正在向状态添加更多数据。
问题:
- 那么,为了获得一些编译时保证,我可以在我的
GenServer
模块中有一个struct
吗? - 而且,如果是,这是正确的方法吗?
- 如果不行,还有哪些选择?
只需声明一个普通结构(可选地在嵌套在您的 GenServer
命名空间中的模块中)并将其用作初始状态:
defmodule Test do
defmodule State do
defstruct ~w|foo bar baz|a
end
use GenServer
def start_link(opts \ []) do
GenServer.start_link(__MODULE__, %State{foo: 42, bar: opts}, name: __MODULE__)
end
@impl true
def init(opts \ []), do: {:ok, opts}
def state, do: GenServer.call(__MODULE__, :state)
@impl true
def handle_call(:state, _from, %State{} = state) do
{:reply, state, state}
end
end
with {:ok, _} <- Test.start_link(pi: 3.14) do
IO.inspect Test.state, label: "State"
end
#⇒ State: %Test.State{bar: [pi: 3.14], baz: nil, foo: 42}