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

наб*_*эли 9 rust

鉴于:

format!("{red}{}{reset}", "text", red = "RED", blue = "BLUE", reset = "RESET");
Run Code Online (Sandbox Code Playgroud)

编译器退出时出错:

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

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

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

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

log!("{red}{}{reset}", "text");
Run Code Online (Sandbox Code Playgroud)

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

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

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

ken*_*ytm 5

如果颜色集都是已知的,您可以使用零长度参数“使用”它们:

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
}
Run Code Online (Sandbox Code Playgroud)

文档concat!

请注意,字符串BLUE, RED,RESET仍将被发送到格式化函数,因此即使不会打印任何内容,也会产生较小的开销。


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

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

log_red!("{}", "text");
Run Code Online (Sandbox Code Playgroud)