问题描述
我正在学习Rust,但有些困惑.
我正在尝试为用户提供将输出写入stdout或提供的文件名的选项.
我从使用extra::getopts
的示例代码开始,该代码位于这里.从那里,在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
特性.有人可以解释我在做什么错吗?
谢谢!
是的,都实现了Write
,但是问题是BufWriter
期望的类型是实现了Writer
的类型T
,并且是T
不能同时是File
和Stdout
.
您必须将两者都强制转换为通用类型(Box<Write>
或&Write
,但是由于无法返回引用,因此必须使用Box
):
fn do_work(input: &str, out: Option<String>) {
let mut out_writer: Box<Write> = BufWriter::new(match out {
Some(ref x) => Box::new(File::create(&Path::new(x)).unwrap()),
None => Box::new(stdout()),
});
out_writer.write(b"Test output\n").unwrap();
}
您还应该正确地处理错误,而不仅仅是使用包装"(为简单起见,在示例中使用).
I'm learning Rust, and I'm somewhat stumped.
I'm trying to give the user the option of writing output to stdout or to a supplied filename.
I started with the example code that's given for using extra::getopts
located here. From there, in the do_work
function, I'm trying to do this:
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" ) );
}
But it outputs the following error:
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 {
^~~~~~~~~~~~~~~~~~~
But I don't understand what the issue is because both File
and StdWriter
implement the Writer
Trait. Can someone explain what I'm doing wrong?
Thanks!
Yes, both implement Write
, but the problem is BufWriter
is expecting a type T
that implements Writer
, and that T
can't be File
and Stdout
at the same time.
You must cast both to the common type (either Box<Write>
or &Write
, but since you cannot return references you have to use Box
):
fn do_work(input: &str, out: Option<String>) {
let mut out_writer: Box<Write> = BufWriter::new(match out {
Some(ref x) => Box::new(File::create(&Path::new(x)).unwrap()),
None => Box::new(stdout()),
});
out_writer.write(b"Test output\n").unwrap();
}
You should also handle errors properly, not just using unwrap (used in example for simplicity).
这篇关于在Rust中写入文件或标准输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!