我正试图在这里描述的守卫中使用记录[1]。如果我使用那里描述的简短形式:
handle(Msg, State) when Msg==#msg{to=void, no=3} ->
......我从未得到过匹配......但是,如果我完全将其扩展为:
handle(Msg, State) when Msg#msg.to==void, Msg#msg.no==3 ->
......一切都很好。正如我对大多数erlang文档所做的那样,我读错了吗?
谢谢, --tim
[1] - http://www1.erlang.org/doc/reference_manual/records.html#id2278275
答案 0 :(得分:11)
当您在警卫中说#msg{to=void, no=3}
时,您未提及的所有字段都将设置为默认字段(通常为undefined
)。因此,你的后卫无法匹配,因为未列出的某些字段不匹配。
我倾向于在可能的情况下始终使用模式而不是保护,因此我将该条款写为:
handle(Msg = #msg{to=void, no=3}, State) ->
...
此模式需要Msg到msg记录(一个msg记录大小的元组,第一个元素是msg
),to
元素必须是void
和{{1元素必须是3. msg记录的其他元素可以是任何东西。
答案 1 :(得分:4)
我看到你已经解决了这个问题。请注意:在惯用的Erlang中,你通常会写这样的匹配:
handle(Msg = #msg{to = void, no = 3}, State) ->
当然,它归结为品味,有时你会想要使用防护装置来获得更令人愉悦的线条对齐。
答案 2 :(得分:4)
您可能希望使用以下模式,简洁
handle(#msg{to=void, no=3}=Msg, State) ->
do_stuff(Msg).
如果您不需要整个msg记录值,但只需要其中的某个字段,那么您可以像这样匹配和销毁
handle(#msg{to=void, no=3, data=Data}, State) ->
do_stuff(Data).
答案 3 :(得分:0)
匹配记录很大时会很麻烦。我处理它的方法是测试记录的第一个元素,它应该是记录名称:
当元素(1,Msg)== msg 时,句柄(Whatever)