有没有一种方法可以将命名参数传递给格式宏,而无需重复变量名?

use*_*932 4 rust rust-macros

使用新版本的Rust,您可以简化结构初始化,如下所示:

Foo {
    a: a,
    b: b,
}
Run Code Online (Sandbox Code Playgroud)

对此

Foo { a, b }
Run Code Online (Sandbox Code Playgroud)

是否可以对format!/ println!-like宏做类似的事情?

现在,我需要这样写:

let a = "a";
let b = "b";
write!(file, "{a} is {b}", a = a, b = b).unwrap();
Run Code Online (Sandbox Code Playgroud)

是否可以使用这样的API编写自己的宏:

let a = "a";
let b = "b";
my_write!(file, "{a} is {b}", a, b).unwrap();
Run Code Online (Sandbox Code Playgroud)

She*_*ter 5

是的,您可以println!和朋友一起编写自己的包装器:

macro_rules! myprintln {
    ($fmt:expr, $($name:ident),*) => { println!($fmt, $($name = $name),*) }
}

fn main() {
    let a = "alpha";
    let b = "beta";
    myprintln!("{a} is {b}", a, b);
}
Run Code Online (Sandbox Code Playgroud)

与完整的格式化程序宏相比,这可能总是会受到限制,但对于您的情况来说可能就足够了。


在格式化宏的当前实现中,这种事情是不可能的:

format!("{a} is {b}", a, b);
Run Code Online (Sandbox Code Playgroud)
macro_rules! myprintln {
    ($fmt:expr, $($name:ident),*) => { println!($fmt, $($name = $name),*) }
}

fn main() {
    let a = "alpha";
    let b = "beta";
    myprintln!("{a} is {b}", a, b);
}
Run Code Online (Sandbox Code Playgroud)

除此之外,我不相信它会永远在这些宏来实现。现有的许多代码如下所示:

format!("{}", foo::bar::function().unwrap() + 2);
Run Code Online (Sandbox Code Playgroud)

那将无法转换成一个合理的名称。

构造初始化的情况也相反-从显式情况到隐式情况。此处提出的此类更改将使现有代码不明确:

println!("{} is {b}", b, b = a);
Run Code Online (Sandbox Code Playgroud)