Allow unused named arguments in Rust's format!() family

后端 未结 1 1202
余生分开走
余生分开走 2021-02-20 16:33

Given:

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

The compilers exits with an error:



        
相关标签:
1条回答
  • 2021-02-20 16:59

    If the set of colors are all known, you could "consume" them with zero-length arguments:

    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)

    Note that the strings BLUE, RED, RESET will still be sent to the formatting function, so it will incur a minor overhead even nothing will be printed.


    I think this is quite error prone, since if you forget a {reset} the rest of your console will become red. I wonder why not write something like:

    macro_rules! log_red {
        ($fmt:expr, $($arg:tt)*) => {
            println!(concat!("RED", $fmt, "RESET"), $($arg)*);
        }
    }
    // also define `log_blue!`.
    
    log_red!("{}", "text");
    
    0 讨论(0)
提交回复
热议问题