如何编写一个宏来显示文件和行号以及可变数量的参数?

问题描述

我在Rust中发现了几个有用的宏,即:message我还发现Rust允许带有可变参数的宏,如here所述:

file!(),line!(),stringify!()

我的目标是以某种方式将所有这些宏合并到一个宏中,以便在故障排除/调试过程中使用。因此,请在下面的示例中调用macro_rules! print_all { ($($args:expr),*) => {{ $( println!("{}",$args); )* }} } 宏:

trace!

应扩展为以下内容

let a: i32 = 1;
let b: i32 = 2;
trace!(a,b)

有可能吗?如果是,那么这样的宏将如何工作?

解决方法

您可以执行以下操作:

macro_rules! trace {
    ($($args: expr),*) => {
        print!("TRACE: file: {},line: {}",file!(),line!());
        $(
            print!(",{}: {}",stringify!($args),$args);
        )*
        println!(""); // to get a new line at the end
    }
}

多次调用print!可能会产生少量开销,因为每次调用都将导致系统调用并且还将检查IO错误。但是,为任意参数构造单个格式字符串将需要一个过程宏,我认为这超出了问题的范围。

您还可以使用BufWriter将其限制为单个系统调用,但这可能不值得。