我试图通过编写基于一些无符号整型一个简单的宏产生一个结构来学习锈病宏系统(u8
,u16
,u32
,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 ]
消息的较高部分包含一些数据/信息,较低部分包含版本控制字段。(这只是一个玩具示例)。
到目前为止,这是我的努力,但是内部重复扩展无法编译:
macro_rules! bitmessage {
(struct $name:ident($n:ty);
$($field_name:ident: $length:expr, $value:expr;)*) => {
struct $name ($n);
$($name.1 = $name.1 | $value << $length)*
};
}
一种解决方案是将相关字节存储在结构中,直接实现(或使用特征)以获取适当的字段,但这将涉及过多的移位逻辑(这没有问题,但是必须有更多的逻辑)方便的方式)。
macro_rules
)您不能在声明性宏中计算表达式。声明性宏仅在输入代码的抽象语法树(AST)的各个部分中创建,删除或移动。在宏扩展期间不会进行任何评估(即使名称为“ expansion”也只是提示)。
最好的办法是在宏展开后创建可在编译时评估的代码。在编译时有效的代码子集是有限的,但将来会增长。
程序宏更复杂,但功能更强大。这些被实现为任意Rust代码,它们可以解析任意Rust代码,输出更多任意Rust代码。
但是,无法重用评估Rust代码的常规方法。您将必须接受文字值并自己进行所有计算。
尚不清楚您希望宏的结果是什么。请记住,宏没有能力“组合”新的Rust概念,它们仅允许您用更少的字符表示现有的重复概念。
因此,我总是建议人们将前两个重复的案例完全写出来。这迫使您编写完整的有效Rust代码并识别它们之间的差异。然后,您可以使用任何常规的Rust技术提取共性。
也可以看看:
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句