在Rust中写入文件或标准输出

在Rust中写入文件或标准输出

本文介绍了在Rust中写入文件或标准输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习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 {
                            ^~~~~~~~~~~~~~~~~~~

但是我不明白问题是什么,因为FileStdWriter都实现了Writer特性.有人可以解释我在做什么错吗?

谢谢!

解决方案

是的,都实现了Write,但是问题是BufWriter期望的类型是实现了Writer的类型T,并且是T不能同时是FileStdout.

您必须将两者都强制转换为通用类型(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中写入文件或标准输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 13:32