有没有办法将命名参数传递给格式化宏而不重复变量名?

时间:2017-07-27 17:01:13

标签: rust rust-macros

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

Foo {
    a: a,
    b: b,
}

到这个

Foo { a, b }

是否可以对format! / println!执行类似的操作(如宏)?

现在我需要这样写:

let a = "a";
let b = "b";
write!(file, "{a} is {b}", a = a, b = b).unwrap();

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

let a = "a";
let b = "b";
my_write!(file, "{a} is {b}", a, b).unwrap();

2 个答案:

答案 0 :(得分:4)

是的,您可以围绕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);
}

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

对于格式化宏的当前实现,这样的事情是不可能的:

format!("{a} is {b}", a, b);
error: there is no argument named `a`
 --> src/main.rs:4:13
  |
4 |     format!("{a} is {b}", a, b);
  |             ^^^^^^^^^^^^

error: there is no argument named `b`
 --> src/main.rs:4:13
  |
4 |     format!("{a} is {b}", a, b);
  |             ^^^^^^^^^^^^

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

format!("{}", foo::bar::function().unwrap() + 2);

这无法转化为合理的名称。

结构初始化案例也采用了另一种方式 - 从显式案例到隐式案例。这里提出的这种改变会使现有代码含糊不清:

println!("{} is {b}", b, b = a);

答案 1 :(得分:-2)

1.5开始,现在有一种本机的方法

format!("x = {}, y = {y}", 10, y = 30);