繁体   English   中英

Erlang 模式匹配位串

[英]Erlang pattern matching bitstrings

我正在编写代码来解码来自二进制协议的消息。 每个消息类型都分配有一个 1 字节的类型标识符,并且每个消息都带有这个类型 id。 消息都以由 5 个字段组成的通用 header 开头。 我的 API 很简单:

decoder:decode(Bin :: binary()) -> my_message_type() | {error, binary()}`

我的第一直觉是通过为每种消息类型编写一个解码 function 并在 fun 参数中完全解码该消息类型来大量依赖模式匹配

decode(<<Hdr1:8, ?MESSAGE_TYPE_ID_X:8, Hdr3:8, Hdr4:8, Hdr5:32, 
         TypeXField1:32, TypeXFld2:32, TypeXFld3:32>>) ->
    #message_x{hdr1=Hdr1, hdr3=Hdr3 ... fld4=TypeXFld3};

decode(<<Hdr1:8, ?MESSAGE_TYPE_ID_Y:8, Hdr3:8, Hdr4:8, Hdr5:32, 
         TypeYField1:32, TypeYFld2:16, TypeYFld3:4, TypeYFld4:32
         TypeYFld5:64>>) ->
    #message_y{hdr1=Hdr1, hdr3=Hdr3 ... fld5=TypeYFld5}.

请注意,虽然消息的前 5 个字段在结构上是相同的,但之后的字段因每种消息类型而异。

我有大约 20 种消息类型,因此有 20 个与上述类似的功能。 我是否使用这种结构多次解码完整消息? 是地道的吗? 我最好只解码 function header 中的消息类型字段,然后解码消息正文中的完整消息吗?

只是同意你的风格非常惯用 Erlang。 不要将解码分成单独的部分,除非您觉得它使您的代码更清晰。 有时进行这种类型的分组可能更合乎逻辑。

编译器很聪明,它编译模式匹配的方式不会多次解码消息。 它将首先解码前两个字段(字节),然后使用第二个字段的值(消息类型)来确定它将如何处理消息的 rest。 无论二进制文件的公共部分有多长,这都有效。

因此,他们无需尝试通过将解码拆分为单独的部分来“帮助”编译器,这不会提高效率。 同样,仅当它使您的代码更清晰时才这样做。

您当前的方法是惯用的 Erlang,因此请继续朝这个方向前进。 不用担心性能,Erlang 编译器在这里做得很好。 如果您的消息确实是完全相同的格式,您可以为其编写宏,但它应该在引擎盖下生成相同的代码。 无论如何,使用宏通常会导致更差的可维护性。 只是出于好奇,为什么当所有记录类型都具有完全相同的字段时,您会生成不同的记录类型? 另一种方法是将消息类型从常量转换为 Erlang 原子并将其存储在一种记录类型中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM