如何从可转位集合中一般地移出数据?

时间:2017-07-09 05:38:38

标签: vector rust move

Rust书中的I/O project example建议克隆命令行args:

fn main() {
    let args: Vec<String> = env::args().collect();
    let config = parse_config(&args);
    // ...
}

struct Config {
    query: String,
    filename: String,
}

fn parse_config(args: &[String]) -> Config {
    let query = args[1].clone();
    let filename = args[2].clone();

    Config {
        query, filename
    }
}

我想将值移到Config结构中以避免复制。

我尝试移动切片:

fn parse_config(args: [String]) -> Config

但得到了错误:

the trait `std::marker::Sized` is not implemented for `[std::string::String]`

这是有道理的,因为它现在正在读取一个未大小的数组。接下来我尝试了泛型:

fn parse_config<T: std::ops::Index<usize, Output=String> + Sized>(args: T) -> Config

出现错误:

cannot move out of indexed content

这也是有道理的,因为它会将矢量保留在invalid state中。我可以移动矢量:

fn parse_config(mut args: Vec<String>) -> Config {
    let query = args.remove(1);
    // ...

但现在该功能与特定容器Vector绑定。

我如何编写一个使用向量并允许我移出其内容的函数,同时仍然保留函数的通用性质?

1 个答案:

答案 0 :(得分:3)

答案是使用消费迭代器:

    ...
    let config = parse_config(args.into_iter());
    ...

fn parse_config<T: Iterator<Item=String>>(mut args: T) -> Config {
    let query = args.nth(1).expect("First arg none");
    let filename = args.nth(0).expect("Second arg none");
    ...
}

请注意,nth函数正在推进和使用迭代器,因此,而不是在2处索引的第二个参数,现在是一个迭代,即0