2017-01-25 10 views
9

Dane:Pozwól nieużywanych nazwanych argumentów w formacie Rust() rodzina

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

kompilatorów wychodzi z błędem:

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

Normalnie, to nie byłby problem jak blue powinny być usunięte, ale mój USECASE jest makro wrapper (uproszczony):

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

Czasami stosuje się go w ten sposób (uproszczony), ale czasami w różnych kolorach, można dostać sens:

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

wyjść kompilatora z analogicznym błędu:

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

czy jest możliwe tylko ignorować nieużywanych argumentów, zamiast erroring na im?

Odpowiedz

3

Jeśli zestaw kolorów są znane, można "konsumować" im argumentów zerowej długości:

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)

Zauważ, że struny BLUE, RED, RESET będzie nadal być wysłane do funkcji formatowania, więc poniesie niewielki narzut, nawet nic nie będzie drukowane.


myślę, że to jest dość podatny na błędy, ponieważ jeśli zapomnisz {reset} reszta konsoli staną się czerwone. Zastanawiam się, dlaczego nie napisać coś takiego:

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

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

„Należy pamiętać, że ciągi niebieski, czerwony, RESET zostaną wysłane”, więc jeśli mogę użyć instancji rzeczą, która implementuje 'Display', że będzie nadal nazywać' Wyświetlaj :: fmt' na nim? "zapomnę {zresetować} resztę", ponieważ mam wiele kolorów dowolnie mieszanych w linii, proste ciągi są tylko dla celów demonstracyjnych. –

+0

Dzięki za odpowiedź, poproś mnie o aktualizację biblioteki pomocniczej i poznanie nowych rzeczy na temat 'Display :: fmt' –

+0

@ набиячлэвэли: Musi wciąż wywoływać' Display :: fmt', biblioteka nie jest jeszcze na tyle mądra, aby wiedzieć '.0' jest specjalne (rzeczy' .N' są obsługiwane w 'Display :: fmt' IIRC). – kennytm