3

我在 Rust 中找到了几个有用的宏,即:file!(), line!(), stringify!()我还发现 Rust 允许使用可变参数的宏,如此所述:

macro_rules! print_all {
    ($($args:expr),*) => {{
        $(
            println!("{}", $args);
        )*
    }}
}

我的目标是以某种方式将所有这些宏组合到一个我将在故障排除/调试期间使用的宏中。trace!所以在下面的例子中调用宏:

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

应该扩展到这样的东西:

println!("TRACE: file: {}, line: {}, a: {}, b: {}", file!(), line!(), a, b);

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

4

1 回答 1

4

你可以这样做:

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 错误。但是,为任意参数构造单个格式化字符串需要一个过程宏,我认为这超出了问题的范围。

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

于 2020-10-15T15:02:19.647 回答