簡體   English   中英

如何評估 Rust 宏系統中的表達式?

[英]How do I evaluate expressions in Rust's macro system?

我試圖通過編寫一個簡單的宏,其基於一些無符號整數類型(結構學習銹宏系統u8u16u32u64 )。 我想要這樣的東西:

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)*
    };
}

一種解決方案可能是將相關字節存儲在結構中,直接(或使用特征)實現它以獲得適當的字段,但這會涉及太多的位移邏輯(沒問題,但必須有更多方便的方式)。

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

聲明性宏 ( macro_rules )

不能對聲明性宏中的表達式求值。 聲明性宏僅創建、刪除或移動輸入代碼的抽象語法樹 (AST) 的一部分。 在宏擴展期間不進行求值(即使名稱“擴展”也是一個提示)。

您能做的最好的事情是創建可以在編譯時評估的代碼,在宏擴展之后。 在編譯時有效的代碼子集是有限的,但將來會增長。

程序宏

程序宏更復雜,但功能更強大。 這些被實現為任意 Rust 代碼,它們可以解析任意 Rust 代碼,輸出更多任意 Rust 代碼。

但是,無法重用評估 Rust 代碼的常規方法。 您將不得不接受文字值並自己進行所有計算。

你的具體例子

目前尚不清楚您希望宏的結果是什么。 請記住,宏沒有能力“組成”新的 Rust 概念,它們只允許您用更少的字符表達現有的重復概念。

因此,我總是建議人們完整地寫出前兩個重復案例。 這迫使您編寫完整的有效 Rust 代碼並確定它們之間的差異。 然后,您可以使用任何普通的 Rust 技術提取共性。

另見:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM