警卫中的记录

发布于 2024-08-25 21:42:01 字数 509 浏览 3 评论 0原文

我正在尝试在守卫中使用记录,如此处所述[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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

策马西风 2024-09-01 21:42:01

当您在防护中说 #msg{to=void, no=3} 时,您未提及的所有字段都将设置为其默认值(通常为 undefined )。所以你的守卫无法匹配,因为一些未列出的字段不匹配。

我倾向于在可能的情况下总是使用模式而不是防护,因此我会将子句写为:

handle(Msg = #msg{to=void, no=3}, State) ->
    ...

此模式需要 Msg 到 msg 记录(一个 msg 记录大小的元组,第一个元素为 msg),to 元素必须为 voidno 元素必须为 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 (usually undefined). 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:

handle(Msg = #msg{to=void, no=3}, State) ->
    ...

This pattern requires Msg to msg record (a tuple the size of an msg record with the first element being msg), the to element must be void and the no element must be 3. The other elements of the msg record can be anything.

山色无中 2024-09-01 21:42:01

我看到你已经解决了问题。请注意:在惯用的 Erlang 中,您通常会这样编写匹配:

handle(Msg = #msg{to = void, no = 3}, State) ->

当然,这取决于品味,有时您会想要使用防护来获得更令人愉悦的行对齐。

I see you solved the problem already. Just a note: in idiomatic Erlang you'd usually write the match like this:

handle(Msg = #msg{to = void, no = 3}, State) ->

Of course, it comes down to taste, and at times you'll want to use guards instead to get more pleasing line alignment.

梦一生花开无言 2024-09-01 21:42:01

您可能想使用以下模式,它很简洁

handle(#msg{to=void, no=3}=Msg, State) ->
    do_stuff(Msg).

如果您不需要整个消息记录值,而只需要其中的某些字段,那么您可以像这样匹配和破坏

handle(#msg{to=void, no=3, data=Data}, State) ->
    do_stuff(Data).

You might want to use the following pattern instead, its succinct

handle(#msg{to=void, no=3}=Msg, State) ->
    do_stuff(Msg).

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(#msg{to=void, no=3, data=Data}, State) ->
    do_stuff(Data).
淡墨 2024-09-01 21:42:01

当记录很大时,匹配记录可能会很麻烦。我处理它的方法是测试记录的第一个元素,它应该是记录名称:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文