![](/img/trans.png)
[英]How can I compute an instance of a type in a function-like procedural macro and return it?
[英]How do I create a function-like procedural macro?
應該如何定義a_proc_macro
以便它“返回”一個 5?
fn main() {
let a = a_proc_macro!();
assert!(a == 5);
}
類函數宏定義看起來像 function 調用的宏。 與宏規則類似
macro_rules!
宏,它們比函數更靈活; 例如,他們可以取未知數量的 arguments。 但是,macro_rules!
只能使用我們在“使用macro_rules!
用於通用元編程”之前。 類似函數的宏采用TokenStream
參數,它們的定義使用 Rust 代碼操縱TokenStream
,就像其他兩種類型的過程宏一樣。 類似函數的宏的一個例子是sql!
可以這樣調用的宏:let sql = sql;(SELECT * FROM posts WHERE id=1);
該宏將解析其中的 SQL 語句並檢查其語法是否正確,這比宏規則的處理要復雜得多
macro_rules!
宏可以做。sql!
宏將被定義如下:#[proc_macro] pub fn sql(input: TokenStream) -> TokenStream {
這個定義類似於自定義派生宏的簽名:我們接收括號內的標記並返回我們想要生成的代碼。
由於Rust 1.45 ,您可以調用類似函數的過程宏作為表達式。
example
├── Cargo.toml
├── example-macro
│ ├── Cargo.toml
│ ├── src
│ │ └── lib.rs
├── src
│ └── main.rs
貨運.toml
[package]
name = "example"
version = "0.1.0"
edition = "2018"
[dependencies]
example-macro = { path = "example-macro" }
src/main.rs
fn main() {
assert_eq!(example_macro::a_proc_macro!(), 5);
}
示例宏/Cargo.toml
[package]
name = "example-macro"
version = "0.1.0"
edition = "2018"
[lib]
proc-macro = true
示例宏/src/lib.rs
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro]
pub fn a_proc_macro(_input: TokenStream) -> TokenStream {
"5".parse().unwrap()
}
也可以看看:
在穩定的 Rust 中直接定義類似表達式的過程宏是不可能的。 如果您可以每晚使用, Shepmaster 的回答顯示了如何使用。
如果您處於穩定狀態,您仍然可以模擬類似表達式的過程宏,如下所示:
在您的情況下,您將像這樣定義程序宏:
#[proc_macro]
pub fn a_proc_macro_impl(_input: TokenStream) -> TokenStream {
"fn output() -> usize { 5 }".parse().unwrap()
}
...輔助macro_rules!
宏遵循這種模式:
macro_rules! a_proc_macro {
($($t:tt)*) => {{
struct _X;
impl _X {
a_proc_macro!($($t)*);
}
_X::output()
}}
}
這是一個 hack,而且很麻煩,但是proc-macro-hack crate 來拯救它,它可以更容易地使用上述技術生成過程宏。 在proc-macro-hack
crate 的幫助下,您可以運行 Shepmaster 在 stable 上的回答中幾乎未更改的代碼:
Cargo.toml
文件並將proc-macro-hack = "0.5.11"
添加到依賴項部分;#[proc_macro_hack] use example_macro::a_proc_macro;
在src/main.rs
中,調用a_proc_macro!
從本地命名空間。example-macro/src/lib.rs
中a_proc_macro
的定義之前添加#[proc_macro_hack::proc_macro_hack]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.