On l'utilise pour envoyer la sortie à stdout:
println!("some output")
Je pense qu'il n'y a pas de macro correspondante pour faire de même pour stderr.
Depuis Rust 1.19, vous pouvez utiliser les macros eprint
et eprintln
:
fn main() {
eprintln!("This is going to standard error!, {}", "awesome");
}
Cela a été initialement proposé dans RFC 1896 .
Vous pouvez voir le implémentation de println!
pour me plonger dans son fonctionnement, mais c'était un peu écrasant lorsque je l'ai lu pour la première fois.
Vous pouvez formater des trucs en stderr en utilisant des macros similaires cependant:
use std::io::Write;
let name = "world";
writeln!(&mut std::io::stderr(), "Hello {}!", name);
Cela vous donnera un unused result which must be used
avertissement cependant, car l'impression vers IO peut échouer (ce n'est pas quelque chose auquel nous pensons habituellement lors de l'impression! Nous pouvons voir que les méthodes existantes simplement paniquer dans ce cas, nous pouvons donc mettre à jour notre code pour faire de même:
use std::io::Write;
let name = "world";
let r = writeln!(&mut std::io::stderr(), "Hello {}!", name);
r.expect("failed printing to stderr");
C'est un peu trop, alors récapitulons-le dans une macro:
use std::io::Write;
macro_rules! println_stderr(
($($arg:tt)*) => { {
let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
r.expect("failed printing to stderr");
} }
);
fn main() {
let name = "world";
println_stderr!("Hello {}!", name)
}
print!
et println!
sont des méthodes pratiques pour écrire sur la sortie standard. Il existe d'autres macros avec les mêmes fonctionnalités de formatage disponibles pour différentes tâches:
write!
et writeln!
pour écrire une chaîne formatée dans un &mut Writer
format!
pour générer simplement un String
formatéPour écrire dans le flux d'erreur standard, vous pouvez utiliser par exemple writeln!
comme ça:
use std::io::Write;
fn main() {
let mut stderr = std::io::stderr();
writeln!(&mut stderr, "Error!").unwrap();
}
C'est fait ainsi:
use std::io::Write;
fn main() {
std::io::stderr().write(b"some output\n");
}
Vous pouvez le tester en envoyant la sortie du programme à /dev/null
pour vous assurer que cela fonctionne (j'ignore l'avertissement):
$ rustc foo.rs && ./foo > /dev/null
foo.rs:4:5: 4:42 warning: unused result which must be used, #[warn(unused_must_use)] on by default
foo.rs:4 io::stderr().write(b"some output\n");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
some output
De même, on peut faire ce qui suit pour stdout:
use std::io::Write;
fn main() {
std::io::stdout().write(b"some output\n");
}
Je pense que cela signifie println!
n'est qu'une commodité: il est plus court et permet également une mise en forme. À titre d'exemple de ce dernier, ce qui suit affiche 0x400
:
println!("0x{:x}", 1024u)
Sans répondre à la question précise, il est peut-être intéressant de noter qu'il existe une caisse log
qui spécifie une interface pour la journalisation à niveau que les autres caisses (par exemple env_logger
) peut remplir.
La sortie de cette journalisation sera envoyée à stderr
, et il y a des avantages supplémentaires pour les utilisateurs, comme la spécification du niveau de journalisation.
Voici à quoi pourrait ressembler un tel enregistreur:
#[macro_use]
extern crate log;
extern crate env_logger;
fn main() {
env_logger::init().unwrap();
error!("this is printed by default");
}
(Exemple adapté de http://burntsushi.net/rustdoc/env_logger/index.html#example )
stderr!("Code {}: Danger, Will Robinson! Danger!", 42);
Les autres réponses génèrent un avertissement d'importation inutilisé avec la dernière version nocturne, alors voici une macro moderne qui fonctionne Just TM.
macro_rules! stderr {
($($arg:tt)*) => (
use std::io::Write;
match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
Ok(_) => {},
Err(x) => panic!("Unable to write to stderr (file handle closed?): {}", x),
}
)
}