我正在努力弄清类似函数的程序宏,并在基础方面苦苦挣扎。
对于初学者来说,我试图创建一个仅打印所有令牌却不执行任何操作的宏:
extern crate proc_macro;
extern crate syn;
use proc_macro::TokenStream;
#[proc_macro]
pub fn my_macro(input: TokenStream) -> TokenStream {
println!( "{:?}", input );
TokenStream::new()
}
然后我尝试在另一个二进制文件中使用它:
extern crate rust_procmacro_test;
fn main() {
rust_procmacro_test::my_macro!( aaa );
}
当我做cargo build
时,我得到了:
Compiling rust_procmacro_test v0.1.0
Compiling procmacro_user v0.1.0
error[E0658]: procedural macros cannot be expanded to statements (see issue #54727)
--> src\main.rs:5:5
|
5 | rust_procmacro_test::my_macro!( aaa );
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TokenStream [Ident { ident: "aaa", span: #0 bytes(114..117) }]
error: aborting due to previous error
它告诉我无法编译,但是宏内的println
有效。发生什么事了?
Issue #54727范围很广,我不确定它与这之间的关系。
我正在使用稳定的i686-pc-windows-gnu,rustc 1.31.1(b6c32da9b 2018-12-18)。
答案 0 :(得分:3)
发生了什么事?
虽然可以在稳定的Rust中定义一个类似函数的程序宏,但调用作为表达式/语句尚不可能。这是因为有concerns about how hygiene should be applied。还有其他可用的位置,例如在项目位置:
extern crate rust_procmacro_test;
rust_procmacro_test::my_macro!( aaa );
fn main() {}
但是宏中的
println
有效
这可能只是实现中的一些懒惰-急切地评估了宏,然后稍后检查功能门。尽管目前这可能效率不高,但是一旦功能完全稳定,就不再重要了。