我正在学习Rust,我有点难过。
我正在尝试为用户提供将输出写入stdout或提供的文件名的选项。
我开始使用extra::getopts
位于here的示例代码。从那里,在do_work
函数中,我正在尝试这样做:
use std::io::stdio::stdout;
use std::io::buffered::BufferedWriter;
fn do_work( input: &str, out: Option<~str> ) {
println!( "Input: {}", input );
println!( "Output: {}", match out {
Some(x) => x,
None => ~"Using stdout"
} );
let out_writer = BufferedWriter::new( match out {
// I know that unwrap is frowned upon,
// but for now I don't want to deal with the Option.
Some(x) => File::create( &Path::new( x ) ).unwrap(),
None => stdout()
} );
out_writer.write( bytes!( "Test output\n" ) );
}
但它输出以下错误:
test.rs:25:43: 28:6 error: match arms have incompatible types: expected `std::io::fs::File` but found `std::io::stdio::StdWriter` (expected struct std::io::fs::File but found struct std::io::stdio::StdWriter)
test.rs:25 let out_writer = BufferedWriter::new( match out {
test.rs:26 Some(x) => File::create( &Path::new( x ) ).unwrap(),
test.rs:27 None => stdout()
test.rs:28 } );
test.rs:25:22: 25:41 error: failed to find an implementation of trait std::io::Writer for [type error]
test.rs:25 let out_writer = BufferedWriter::new( match out {
^~~~~~~~~~~~~~~~~~~
但我不明白这是什么问题,因为File
和StdWriter
都实现了Writer
特征。有人可以解释我做错了吗?
谢谢!
答案 0 :(得分:8)
自2014年以来,Rust已经发生了很多变化,所以这里有一个适用于Rust 1.15.1的答案:
let out_writer = match out {
Some(x) => {
let path = Path::new(x);
Box::new(File::create(&path).unwrap()) as Box<Write>
}
None => Box::new(io::stdout()) as Box<Write>,
};
这与@Arjan's answer几乎相同,只是~
被Box
取代,而且有些名称已更改。我要离开BufferedWriter
,但如果你想要,我相信它现在被命名为BufWriter
。
答案 1 :(得分:5)
是的,都是Write
的实施,但问题是BufWriter
期望实现T
的{{1}}类型,Writer
不能<{1}}和T
在同一时间。
您必须将两者都投放到公共类型(File
或Stdout
,但由于您无法返回引用,因此必须使用Box<Write>
):
&Write
您还应该正确处理错误,而不仅仅是使用unwrap(为简单起见,在示例中使用)。