Elixir 理解 GenServer
Elixir understanding GenServer
我是 Elixir 的新手,正在阅读一本书并做一些例子。这是让我在这里提问的一段代码:
defmodule Sequence.Server do
use GenServer
def init(initial_number)do
{:ok,initial_number}
end
def handle_call(:next_number, _from, current_number)do
{:reply, current_number,current_number+1}
end
end
据我所知,init 函数在服务器初始化时被调用,我们正在定义一些参数 - 这将是服务器的初始状态。让我感到困惑的是 current_number 和 initial_number 如何相互关联,我的意思是无处可去在代码中我们说的是类似的东西
current_number = initial_number
因为当我调用 GenServer.call(some_process_id, :next_number)
它从 100 开始,例如如果 start_link 的参数是 100。Elixir 如何理解它必须开始从 100 开始,当我们在初始状态和 current_number
参数之间没有任何映射时
init
的结果是{:ok, initial_state}
,其中状态值由GenServer
持有。
handle_call
的签名实际上是handle_call(request, from, current_state)
,return是{:reply, result, new_state}
。
这意味着当您执行 GenServer.call(pid, :next_number)
时,会导致调用 handle_call(:next_number, _from, state)
,其中状态 —— 作为 current_number
传递 —— 作为 initial_number
开始handle_call
的结果保存了一个值为 current_number
.
的新状态
下次调用 GenServer.call(pid, :next_number)
时,它会以新状态调用,而你 return 新状态,依此类推...
init/1
的目的是设置GenServer
的内部状态。修改此 GenServer
内部状态的唯一方法是通过 call
-ing、cast
-ing 或发送常规消息(然后由 handle_info/2
回调处理).
将调用这些函数(分别为 handle_call/3
和 handle_cast/2
),并将 GenServer
的内部状态作为函数参数的最后一个参数传入。
考虑场景:
- 您正在用数字
100
初始化 GenServer
。
- 您向
GenServer
- :next_number
. 发送了一条消息(更具体地说是 call
)
- 这会调用您的
handle_call(:next_number, _from, current_number)
回调函数,其中 current_number
的初始值为 100
。
- 作为此函数的 return 值,您指定了元组:
{:reply, current_number,current_number+1}
,您应该理解为:reply
(元组的第一个元素)表示它将回复给来电者;元组的第二个元素将是值 returned 给调用者(在这种情况下,它将是数字 100
);元组的最后一个元素将是 GenServer
- current_number+1
的 新状态,因此 101
.
- 当你发送另一个
:next_number
call
到这个 GenServer
时,它会遵循前面的步骤,除了,内部状态现在是 101
,并且之后return 从函数中,新状态将是 102
,等等...
我是 Elixir 的新手,正在阅读一本书并做一些例子。这是让我在这里提问的一段代码:
defmodule Sequence.Server do
use GenServer
def init(initial_number)do
{:ok,initial_number}
end
def handle_call(:next_number, _from, current_number)do
{:reply, current_number,current_number+1}
end
end
据我所知,init 函数在服务器初始化时被调用,我们正在定义一些参数 - 这将是服务器的初始状态。让我感到困惑的是 current_number 和 initial_number 如何相互关联,我的意思是无处可去在代码中我们说的是类似的东西
current_number = initial_number
因为当我调用 GenServer.call(some_process_id, :next_number)
它从 100 开始,例如如果 start_link 的参数是 100。Elixir 如何理解它必须开始从 100 开始,当我们在初始状态和 current_number
参数之间没有任何映射时
init
的结果是{:ok, initial_state}
,其中状态值由GenServer
持有。
handle_call
的签名实际上是handle_call(request, from, current_state)
,return是{:reply, result, new_state}
。
这意味着当您执行 GenServer.call(pid, :next_number)
时,会导致调用 handle_call(:next_number, _from, state)
,其中状态 —— 作为 current_number
传递 —— 作为 initial_number
开始handle_call
的结果保存了一个值为 current_number
.
下次调用 GenServer.call(pid, :next_number)
时,它会以新状态调用,而你 return 新状态,依此类推...
init/1
的目的是设置GenServer
的内部状态。修改此 GenServer
内部状态的唯一方法是通过 call
-ing、cast
-ing 或发送常规消息(然后由 handle_info/2
回调处理).
将调用这些函数(分别为 handle_call/3
和 handle_cast/2
),并将 GenServer
的内部状态作为函数参数的最后一个参数传入。
考虑场景:
- 您正在用数字
100
初始化GenServer
。 - 您向
GenServer
-:next_number
. 发送了一条消息(更具体地说是 - 这会调用您的
handle_call(:next_number, _from, current_number)
回调函数,其中current_number
的初始值为100
。 - 作为此函数的 return 值,您指定了元组:
{:reply, current_number,current_number+1}
,您应该理解为:reply
(元组的第一个元素)表示它将回复给来电者;元组的第二个元素将是值 returned 给调用者(在这种情况下,它将是数字100
);元组的最后一个元素将是GenServer
-current_number+1
的 新状态,因此101
. - 当你发送另一个
:next_number
call
到这个GenServer
时,它会遵循前面的步骤,除了,内部状态现在是101
,并且之后return 从函数中,新状态将是102
,等等...
call
)