我是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 是如何相互关联的,我的意思是在代码中没有我们在说这样的话
当前编号=初始编号
例如,当我调用GenServer.call(some_process_id, :next_number)
时,如果 start_link 的参数为100,则它从100开始。当我们之间没有任何映射时,Elixir如何理解它必须从100开始初始状态和current_number
参数
答案 0 :(得分:7)
init/1
的目的是设置GenServer
的内部状态。修改此GenServer
内部状态的唯一方法是通过call
-ing,cast
-ing或发送常规消息(然后由handle_info/2
回调处理)。
这些函数(分别为handle_call/3
和handle_cast/2
)将以GenServer
的内部状态作为函数参数的最后一个参数传递的方式调用。
考虑场景:
GenServer
初始化100
。call
-GenServer
发送了一条消息(更具体地说是:next_number
。handle_call(:next_number, _from, current_number)
回调函数,其中current_number
的初始值为100
。{:reply, current_number,current_number+1}
,您应该理解该元组:reply
(元组的第一个元素)表示它将回复调用方;元组的第二个元素将是返回给调用方的值(在这种情况下,它将是数字100
);元组的最后一个元素将是GenServer
-current_number+1
的新状态,所以101
。:next_number
发送另一个call
GenServer
时,它将按照之前的步骤进行,除了内部状态现在为101
,并且从函数,新状态将为102
,依此类推... 答案 1 :(得分:1)
init
的结果为{:ok, initial_state}
,其中状态值由GenServer
保留。
handle_call
的签名实际上是handle_call(request, from, current_state)
,并返回{: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)
时,它会以新状态被调用,然后返回新状态,依此类推...