根据参数分配

时间:2015-10-07 07:07:45

标签: rust

我试图编写一个从文件或标准输入中获取输入的程序,具体取决于是否传递了命令行参数。为此,我使用了getopts,它允许你获得带有参数值的Option<String>。如果值为Some(filename),我想打开该文件并在其上创建一个缓冲读取器。如果是None,我想将流设置为标准输入。

let input: Box<Read> = match matches.opt_str("i") {
    Some(ifname) => Box::new(BufReader::new(File::open(ifname).unwrap())),
    None => Box::new(io::stdin()),
};

因此,输入类型需要为&readBox<Read>,因为StdinBufReader是不兼容的类型。显然&Read没有工作,因为没有变量实际上拥有足够长的范围内的对象。所以我尝试使用Box<Read>,但这仍然让我错误地认为input没有足够长的时间。

做这样的事情的生锈(生锈?质朴?)是什么样的?

MCVE:

use std::io;
use std::borrow::BorrowMut;
use std::io::{BufReader,BufWriter,Read,Write};
use std::fs::File;

fn rc4(key: &[u8], input: &mut Read, output: &mut Write) {
    // Read and write here                                                                                                                                                                           
}

fn main() {
    let mut input: Box<Read> = match Some("file-from-parser.txt") {
        Some(ifname) => Box::new(BufReader::new(File::open(ifname).unwrap())),
        None => Box::new(io::stdin()),
    };

    rc4(&[1u8, 2, 3], input.borrow_mut(), &mut io::stdout());
}

1 个答案:

答案 0 :(得分:4)

以下代码有效:

use std::io;
use std::io::{BufReader, Read, Write};
use std::fs::File;

fn rc4(key: &[u8], input: &mut Read, output: &mut Write) {
    // Read and write here                                                                                                                                                                           
}

fn main() {
    let mut input: Box<Read> = match Some("file-from-parser.txt") {
        Some(ifname) => Box::new(BufReader::new(File::open(ifname).unwrap())),
        None => Box::new(io::stdin()),
    };

    rc4(&[1u8, 2, 3], &mut input, &mut io::stdout());
}

请注意,绝对没有理由使用borrow_mut(),因为在必要时,对Box指针的引用会自动强制引用其内部引用。此外,使rc4使用对泛型类型的引用而不是特征对象更为惯用:

fn rc4<R: Read, W: Write>(key: &[u8], input: &mut R, output: &mut W)

甚至

fn rc4<R: Read, W: Write>(key: &[u8], input: R, output: W)

(这是有效的,因为如果&mut RReadRReadWrite同样适用;您可能需要写{ {1}}和/或mut input: R取决于您使用的API)

上述代码无需更改这两个签名即可使用。

至于为什么mut output: W不起作用,我没有任何想法。在我看来,它应该工作。也许这是与borrow_mut()是特质对象这一事实的某种互动。

此外,有一种方法可以完全避免Box<Read>

Box

这里我们将每个阅读器存储在单独的变量中,并返回对其中一个的引用。