如何评估Rust的宏系统中的表达式?

时间:2018-03-30 15:13:00

标签: rust rust-macros

我试图通过编写一个基于某些无符号整数类型生成结构的简单宏来学习Rust宏系统(u8u16u32,{ {1}})。我想要这样的东西:

u64

更具体地说,我正在寻找某种方法将某些信息存储在具有各种偏移的无符号整数类型中。一个用例是读取一些字节并构造某种"消息":

bitmessage! {
    struct Header(u16);
    version: 8, 5; // the first number is the length, second is value
    data: 8, 5;
}

消息的较高部分包含一些数据/信息,较低部分包含版本控制字段。 (这只是一个玩具示例)。

到目前为止,这是我的努力,但内部重复扩展无法编译:

[ 15 14 13 12 11 10 09 08 | 07 06 05 04 03 02 01 01 ]

一个解决方案可能是将相关字节存储在结构中,直接实现(或使用特征)来获取相应的字段,但这会涉及过多的位移逻辑(没有问题,但必须是一种更方便的方式)。

我知道bitflagsbitfield。它们都不符合我的用例。

1 个答案:

答案 0 :(得分:2)

您无法评估宏中的表达式。宏只创建,删除或移动输入代码的抽象语法树(AST)的各个部分。在宏扩展期间没有评估(甚至名称“扩展”是一个提示)。

您可以做的最好的事情是创建在扩展宏之后可以在编译时评估的代码。在编译时有效的代码子集是有限的,但将来会增长。

对于您的具体示例,我们很不清楚您希望宏的结果是什么。请记住,宏不具备“构成”新Rust概念的能力,它们只允许用较少的字符表达现有的重复概念。

因此,我总是建议人们完全写出第一个两个重复的案例。这会强制您编写完整的有效Rust代码并识别它们之间的差异。然后,您可以使用任何常规Rust技术提取通用性。

另见: