使用此命令将输出发送到stdout:
println!("some output")
我认为没有相应的宏可以对stderr执行相同的操作。
在Rust 1.19之后
从Rust 1.19开始,您可以使用eprint和eprintln宏:
fn main() {
eprintln!("This is going to standard error!, {}","awesome");
}
这最初是在RFC 1896中提出的。
在Rust 1.19之前
您可以看到println!的实现以深入了解它的工作原理,但是当我初次阅读它时有点不知所措。
您可以使用类似的宏将内容格式化为stderr:
use std::io::Write;
let name ="world";
writeln!(&mut std::io::stderr(),"Hello {}!", name);
但是,这会给您一个unused result which must be used警告,因为打印到IO可能会失败(这不是我们通常在打印时会考虑的事情!)。我们可以看到,在这种情况下,现有方法简直很着急,因此我们可以更新代码以进行相同操作:
use std::io::Write;
let name ="world";
let r = writeln!(&mut std::io::stderr(),"Hello {}!", name);
r.expect("failed printing to stderr");
这有点多,所以让我们将其包装回宏中:
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)
}
因此,它们的println_stderr!("Hello {}!", name)与writeln!(&mut std::stdio::stderr(),"Hello {}!", name)两者几乎具有相同的作用?
它们执行相同的操作,但是宏可以处理失败情况(返回值),而不会产生任何麻烦。 没有它,您将得到警告。
您还可以执行writeln!(...).unwrap();以最简单的方式处理可能的故障。
print!和println!是用于写入标准输出的便捷方法。还有其他具有相同格式设置功能的宏可用于不同的任务:
write!和writeln!将格式化的字符串写入&mut Writer
format!仅生成格式化的String
要写入标准错误流,您可以使用例如writeln!像这样:
use std::io::Write;
fn main() {
let mut stderr = std::io::stderr();
writeln!(&mut stderr,"Error!").unwrap();
}
虽然没有回答确切的问题,但是可能有一个log条板箱,它指定了其他条板箱(例如env_logger)可以实现的水平记录的接口。
这样的日志记录的输出将发送到stderr,并且为用户带来其他好处,例如指定日志级别。
这就是使用这种记录器的样子:
#[macro_use]
extern crate log;
extern crate env_logger;
fn main() {
env_logger::init().unwrap();
error!("this is printed by default");
}
(示例摘自http://burntsushi.net/rustdoc/env_logger/index.html#example)
这样做是:
use std::io::Write;
fn main() {
std::io::stderr().write(b"some output
");
}
您可以通过将程序输出发送到/dev/null进行测试以确保其正常工作(我忽略了警告):
$ 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
");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
some output
同样,可以对stdout执行以下操作:
use std::io::Write;
fn main() {
std::io::stdout().write(b"some output
");
}
我认为这意味着println!只是一种便利:它更短并且还允许进行一些格式化。作为后者的示例,以下显示0x400:
println!("0x{:x}", 1024u)
目标
stderr!("Code {}: Danger, Will Robinson! Danger!", 42);
笔记
其他答案会在最近的夜间生成未使用的导入警告,因此这是Just Works 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),
}
)
}
在每晚的Rust Playground上,我的答案都没有警告。 你在看什么
此解决方案不起作用:错误:非项目语句后不允许导入
如果您在另一个语句之后的块中使用宏,这对我来说就是这样。 如果在另一个块中用use和match包装内部位,则对我有用。 所以($($arg:tt)*) => ({ use ... })