Erlang中的模式不匹配
Posted
技术标签:
【中文标题】Erlang中的模式不匹配【英文标题】:Pattern not matching in Erlang 【发布时间】:2015-03-18 13:24:14 【问题描述】:我正在打这个电话:
add(Login, Pass, Role) ->
gen_server:call(?SERVER, add, Login, Pass, Role).
我希望它匹配:
handle_call(State, add, Login, Pass, Role) ->
io:format("add ~n"),
Db = State#state.db,
case lists:keyfind(Login, 1, Db) of
false->
io:format("add - reg new ~n"),
reply, registered, State#statedb=[Login, erlang:md5(Pass), Role, ""|Db];
Key, Result->
reply, invalid_params, Db
end.
但它总是去:
handle_call(_Request, _From, State) ->
io:format("undef ~n"),
Reply = ok,
reply, Reply, State.
怎么了?
【问题讨论】:
【参考方案1】:这种行为似乎是有效的,
handle_call
有这样的规格:
-spec(handle_call(Request :: term(), From :: pid(), Tag :: term(),
State :: #state) ->
reply, Reply :: term(), NewState :: #state |
reply, Reply :: term(), NewState :: #state, timeout() | hibernate |
noreply, NewState :: #state |
noreply, NewState :: #state, timeout() | hibernate |
stop, Reason :: term(), Reply :: term(), NewState :: #state |
stop, Reason :: term(), NewState :: #state).
如果你可以看看这里 http://erlang.org/doc/man/gen_server.html#Module:handle_call-3
此外,对于 otp 默认行为,最好首先使用模板。对于 gen_server 例如https://gist.github.com/kevsmith/1211350
干杯!
【讨论】:
【参考方案2】:在使用gen_server
行为的模块中,handle_call
回调函数应采用三个参数。但是,您已经定义了两个不同的函数,handle_call/2
和 handle_call/3
。 (在 Erlang 中,具有相同名称但采用不同数量参数的函数被视为不同的函数。)
由于gen_server
模块仅查找handle_call/3
而忽略handle_call/2
,因此始终调用您的“undef”函数。
要解决此问题,请将函数更改为采用(忽略的)第二个参数,并将请求放在首位,将状态放在最后:
handle_call(add, Login, Pass, Role, _From, State) ->
将end.
改为end;
——.
分隔不同的函数,而;
分隔同一函数的不同子句。
【讨论】:
State
是最后一个参数:它是handle_call(Req, _From, State)
。
谢谢!没注意到...现在修复了。
handle_cast/2 需要 2 个参数,handle_call/3 总是需要 3,gen_event 有 handle_call/2以上是关于Erlang中的模式不匹配的主要内容,如果未能解决你的问题,请参考以下文章