记录在一个警卫

时间:2010-03-23 17:22:05

标签: erlang

我正试图在这里描述的守卫中使用记录[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

4 个答案:

答案 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)