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_numberinitial_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/3handle_cast/2),并将 GenServer 的内部状态作为函数参数的最后一个参数传入。

考虑场景:

  1. 您正在用数字 100 初始化 GenServer
  2. 您向 GenServer - :next_number.
  3. 发送了一条消息(更具体地说是 call
  4. 这会调用您的 handle_call(:next_number, _from, current_number) 回调函数,其中 current_number 的初始值为 100
  5. 作为此函数的 return 值,您指定了元组:{:reply, current_number,current_number+1},您应该理解为:reply(元组的第一个元素)表示它将回复给来电者;元组的第二个元素将是值 returned 给调用者(在这种情况下,它将是数字 100);元组的最后一个元素将是 GenServer - current_number+1 新状态,因此 101.
  6. 当你发送另一个 :next_number call 到这个 GenServer 时,它会遵循前面的步骤,除了,内部状态现在是 101,并且之后return 从函数中,新状态将是 102,等等...