警卫中的记录
我正在尝试在守卫中使用记录,如此处所述[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
I'm attempting to use a record in a guard as described here[1]. If I use the short form described there:
handle(Msg, State) when Msg==#msg{to=void, no=3} ->
... I never get a match... however, if I fully expand it to:
handle(Msg, State) when Msg#msg.to==void, Msg#msg.no==3 ->
... all is well. As it seems I do with most erlang docs, am I reading it wrong?
Thanks,
--tim
[1] - http://www1.erlang.org/doc/reference_manual/records.html#id2278275
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您在防护中说
#msg{to=void, no=3}
时,您未提及的所有字段都将设置为其默认值(通常为undefined
)。所以你的守卫无法匹配,因为一些未列出的字段不匹配。我倾向于在可能的情况下总是使用模式而不是防护,因此我会将子句写为:
此模式需要 Msg 到 msg 记录(一个 msg 记录大小的元组,第一个元素为
msg
),to
元素必须为void
,no
元素必须为 3。msg 记录的其他元素可以是任何内容。When you say
#msg{to=void, no=3}
in a guard, all the fields that you haven't mentioned will be set to their default (usuallyundefined
). So your guard is failing to match because some of the fields not listed don't match.I tend to always use a pattern rather than a guard where possible, so I would write the clause as:
This pattern requires Msg to msg record (a tuple the size of an msg record with the first element being
msg
), theto
element must bevoid
and theno
element must be 3. The other elements of the msg record can be anything.我看到你已经解决了问题。请注意:在惯用的 Erlang 中,您通常会这样编写匹配:
当然,这取决于品味,有时您会想要使用防护来获得更令人愉悦的行对齐。
I see you solved the problem already. Just a note: in idiomatic Erlang you'd usually write the match like this:
Of course, it comes down to taste, and at times you'll want to use guards instead to get more pleasing line alignment.
您可能想使用以下模式,它很简洁
如果您不需要整个消息记录值,而只需要其中的某些字段,那么您可以像这样匹配和破坏
You might want to use the following pattern instead, its succinct
If you don't need the whole msg record value, but only some field within it then you can match and destruct like this
当记录很大时,匹配记录可能会很麻烦。我处理它的方法是测试记录的第一个元素,它应该是记录名称:
handle(Whatever) when element(1,Msg) == msg
Matching records can be a hassle when they are large. The way I deal with it is by testing the first element of the record, which should be the record name:
handle(Whatever) when element(1,Msg) == msg