2

我试图让我的头脑围绕类似函数的过程宏并努力学习基础知识。

首先,我尝试创建一个只打印所有标记并且什么都不做的宏:

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在宏内部有效。怎么了?

问题 #54727非常广泛,我不确定它与此有何关系。

我正在使用 stable-i686-pc-windows-gnu、rustc 1.31.1 (b6c32da9b 2018-12-18)。

4

1 回答 1

4

怎么了?

虽然可以在稳定的 Rust 中定义类似函数的过程宏,但还不能将其调用为表达式/语句。这是因为人们担心应该如何应用卫生。还有其他可用的位置,例如在项目位置:

extern crate rust_procmacro_test;

rust_procmacro_test::my_macro!( aaa );

fn main() {}

println在宏内部有效

这可能只是实现中的一些懒惰——急切地评估宏,然后稍后检查特征门。虽然目前这可能效率低下,但一旦功能完全稳定,它就无关紧要了。

于 2019-01-14T01:06:37.853 回答