Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如果clap没有给出位置参数,如何使用STDIN?_Rust_Clap - Fatal编程技术网

Rust 如果clap没有给出位置参数,如何使用STDIN?

Rust 如果clap没有给出位置参数,如何使用STDIN?,rust,clap,Rust,Clap,我有一个clap应用程序如下: let m = App::new("test") .arg( Arg::with_name("INPUT") .help("a string to be frobbed") .multiple(true), ) .get_matches(); fn process<I: IntoIterator<Item = String>>(strings: I)

我有一个clap
应用程序
如下:

let m = App::new("test")
    .arg(
        Arg::with_name("INPUT")
            .help("a string to be frobbed")
            .multiple(true),
    )
    .get_matches();
fn process<I: IntoIterator<Item = String>>(strings: I) {
    for string in strings {
        frob(string);
    }
}
match m.values_of("INPUT") {
    Some(values) => process(values.map(|ln| ln.to_string())),
    None => process(io::stdin().lock().lines().map(|ln| ln.unwrap())),
}
如果存在任何
myapp str1 str2 str3
,我希望将参数作为字符串的一个iterable读取,但如果没有,则充当过滤器并从stdin
cat afile | myapp
读取一个iterable行。这是我的尝试:

let stdin = io::stdin();
let strings: Box<Iterator<Item = String>> = if m.is_present("INPUT") {
    Box::new(m.values_of("INPUT").unwrap().map(|ln| ln.to_string()))
} else {
    Box::new(stdin.lock().lines().map(|ln| ln.unwrap()))
};

for string in strings {
    frob(string)
}
让stdin=io::stdin();
let strings:Box=如果m.u存在(“输入”){
框::新建(m.values_of(“INPUT”).unwrap().map(|ln | ln.to_string())
}否则{
框::新建(stdin.lock().lines().map(|ln | ln.unwrap())
};
对于字符串中的字符串{
弗罗布(弦)
}
我相信,因为我只需要
迭代器
特性,所以
是唯一的选择。这是正确的吗?

很少有“唯一的出路”,这种情况也不例外。另一种方法是使用静态调度而不是动态调度

主处理代码需要字符串迭代器作为输入。因此,您可以定义如下处理函数:

let m = App::new("test")
    .arg(
        Arg::with_name("INPUT")
            .help("a string to be frobbed")
            .multiple(true),
    )
    .get_matches();
fn process<I: IntoIterator<Item = String>>(strings: I) {
    for string in strings {
        frob(string);
    }
}
match m.values_of("INPUT") {
    Some(values) => process(values.map(|ln| ln.to_string())),
    None => process(io::stdin().lock().lines().map(|ln| ln.unwrap())),
}
编译器将发出两个不同版本的
process()
,每个迭代器类型对应一个版本。每个版本静态调用为其编译的迭代器函数,并且在
match
语句中只有一个分派到正确函数

(我可能有些细节搞错了,但你明白了。)

另一方面,您的版本使用类型
Box
,因此迭代器将在堆上分配,并且每次在迭代器上调用
next()
时都会有一个动态调度。这可能很好


当然,在两种不同类型的输入之间构建代码和分配的方法还有很多,例如,使用
板条箱中的
类型,或者简单地为这两种情况的
循环编写两种不同的
。选择哪一个取决于与代码的其他要求、性能要求和个人偏好之间的权衡。

最好单独发布问题,而不是将问题合并为一个问题。这样,它可以帮助人们回答你的问题,也可以帮助其他人寻找你的问题。我已经删除了你的第二和第三个问题;把重点放在标题中的问题上。还有。你也可以做一些类似于
fn进程(strings:I)的事情,其中I:into迭代器,I::Item:AsRef
,以避免强制分配
String
@Shepmaster是的,当我写完这个答案时,我意识到我真的不知道这个问题是什么,但因为我已经打了这个,我还是把它贴了出来。你可以做很多事情,但我们不知道OP想要解决什么问题。:)我想我在这里真的遇到了一个相当复杂的问题,
或者
板条箱看起来非常有用,它具有转发迭代器的功能。总的来说,我不确定对我的用例来说什么是“最好的”——这只是我为了好玩而写的东西,平均调用时间已经是
0.00
,所以我显然没有达到任何性能限制。感谢您向我展示了静态分派选项。@ScottColby如果您编写代码是为了好玩,我建议您使用最有趣的方法。:)Rust通常使用静态分派,仅对trait对象使用动态分派,即早期版本的Rust中的类型,如
&dyn trait
Box
,writed
&trait
Box
。然而,只有在遇到性能问题时,才真正需要关心这一点,在这种情况下,您需要分析代码并找出瓶颈所在。例如,在这种情况下,优化程序可能能够将调用
next()
的查找从循环中拉出。