如何将参数传递给 gen_server 函数?

How to pass parameter to a gen_server function?

我有一个 gen_server,它会在每次调用 increment() 函数时递增计数器。

-module(genserver).
-export([start_link/0, start/0, increment/0]).
-behaviour(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

init([]) ->
    {ok, "counter.txt"}.

start() ->
    gen_server:start({local, ?MODULE}, ?MODULE, [], []).

increment() ->
    gen_server:call(?MODULE, increment).

handle_call(increment, _From, File) ->
    Counter = case file:read_file(File) of
        {ok, Binary} -> binary_to_integer(Binary);
        {error, enoent} -> 0
    end,
    ok = file:write_file(File, integer_to_binary(Counter + 1)).

handle_cast(_Req, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

这是 shell 执行示例

Eshell V7.3  (abort with ^G)
1> c("C:/Users/guga.melkadze/Desktop/testgen"). 
{ok,testgen}
2> testgen:start().
{ok,<0.39.0>}
3> testgen:increment().
920
4> testgen:increment().
921
5> testgen:increment().
922

现在我每次调用genserver:increment()方法都需要发送一个参数。例如 genserver:increment(someParameter)。我该如何实现?

更改 increment 函数以发送一个元组而不仅仅是一个原子:

increment(N) ->
    gen_server:call(?MODULE, {increment, N}).

并更新 handle_call 子句以使用它:

handle_call({increment, N}, _From, File) ->
    Counter = case file:read_file(File) of
        {ok, Binary} -> binary_to_integer(Binary);
        {error, enoent} -> 0
    end,
    ok = file:write_file(File, integer_to_binary(Counter + N)).

请注意,您的 handle_call 函数不是 return gen_server 行为所期望的值类型,因此此过程可能会在每次请求后崩溃。您应该在最后一行添加类似这样的内容:

{reply, ok, File}.