Rust 函数名称(调用者)或宏内的任何其他上下文

标签 rust macros

Rust 有没有办法在宏中获取“调用”函数名称或任何其他上下文信息?

例子:

#[macro_export]
macro_rules! somemacro {
    ( $x:expr ) => {
        {
          // access function name (etc..) that called this macro
        }
    };
}

最佳答案

这可以使用程序宏来完成:

extern crate proc_macro;
use proc_macro::TokenStream;

#[proc_macro_attribute]
pub fn with_name(_: TokenStream, item: TokenStream) -> TokenStream {
    let mut input = syn::parse_macro_input!(item as syn::ItemFn);

    let fn_name = input.ident.to_string();
    let const_decl = quote::quote! {
        const THIS_FN: &str = #fn_name;
    };

    input.block.stmts.insert(0, syn::parse(const_decl.into()).unwrap());

    let output = quote::quote! {
        #input
    };

    output.into()
}

cargo .toml:

[package]
name = "with_name"
version = "0.1.0"
edition = "2018"

[lib]
proc-macro = true

[dependencies]
quote = "0.6.12"
syn = { version = "0.15.37", features = ["full"] }

可以用作:

#[with_name::with_name]
fn foo() {
    println!("Name: {}", THIS_FN);
}

fn main() {
    foo();
}

另请注意,如果您只关心模块,there is a built-in macro for that :

mod test {
    pub fn foo() {
        println!("Module: {}", module_path!());
    }
}

fn main() {
    test::foo();
}

(link to playground)

关于Rust 函数名称(调用者)或宏内的任何其他上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56718336/

相关文章:

条件编译: compile once if macro is present at least once

c - Atmel C 引脚操作宏

macros - 简化嵌套循环的 Rust 宏规则

multithreading - 如何使用Rayon进行PI的并行计算

rust - 如何说服借用检查器不再使用借用的引用

generics - 我如何传达一个带有引用的泛型类型只需要通过函数调用生存?

rust - 我如何指定在 Cargo 工作区的根目录中默认运行哪个 crate `cargo run`?

opengl - 如何在可执行文件和DLL之间使用OpenGL函数指针?

c - Windbg 堆栈跟踪显示宏扩展之前或之后的行号

C++ 自定义#pragma