允许Rust的格式!()系列中未使用的命名参数

时间:2017-01-25 00:27:12

标签: rust

假设:

format!("{red}{}{reset}", "text", red = "RED", blue = "BLUE", reset = "RESET");

编译器退出时出错:

error: named argument never used
  --> example.rs:1:47
   |
 1 |         format!("{red}{}{reset}", "text", red = "RED", blue = "BLUE", reset = "RESET");
   |                                                        ^^^^^^^^^^^^^

通常,这不会是一个问题,因为blue应该删除,但我的usecase是一个包装宏(简化):

macro_rules! log {
    ($fmt:expr, $($arg:tt)*) => {
        println!($fmt, $($arg)*, blue = "BLUE", red = "RED", reset = "RESET");
    };
}

有时,它会像这样使用(简化),但有时会使用不同的颜色,你会得到要点:

log!("{red}{}{reset}", "text");

编译器退出时出现类似错误:

error: named argument never used
  --> example.rs:3:26
   |
3  |         println!($fmt, $($arg)*, blue = "BLUE", red = "RED", reset = "RESET");
   |                                  ^^^^^^^^^^^^^

是否可以忽略未使用的参数,而不是对它们进行错误处理?

1 个答案:

答案 0 :(得分:3)

如果这组颜色都是已知的,你可以“消费”#34;他们使用零长度参数:

macro_rules! log {
    ($fmt:expr, $($arg:tt)*) => {
        println!(concat!($fmt, "{blue:.0}{red:.0}{reset:.0}"),  // <--
                 $($arg)*,
                 blue="BLUE", 
                 red="RED", 
                 reset="RESET")
    }
}

fn main() {
    log!("{red}{}{reset}", "<!>");
    // prints: RED<!>RESET
}

Docs for concat! macro

请注意,字符串BLUEREDRESET仍将发送到格式化功能,因此即使没有任何内容打印,也会产生轻微的开销。

我认为这很容易出错,因为如果你忘了{reset},你控制台的其余部分就会变红。我想知道为什么不写下这样的东西:

macro_rules! log_red {
    ($fmt:expr, $($arg:tt)*) => {
        println!(concat!("RED", $fmt, "RESET"), $($arg)*);
    }
}
// also define `log_blue!`.

log_red!("{}", "text");