Rust字符串生存期和迭代器适配器(生命周期编译错误)

时间:2014-11-14 23:26:19

标签: rust

我正在使用CSV,因此我需要修剪换行符并在每行的逗号上拆分,并过滤掉任何带有“?”的行。在他们中间。

let instances: Vec<Vec<&str>> = file.lines()
    .map(|x| x.unwrap())
    .filter(|x| !(x.contains("?")))
    .map(|x| x.as_slice().trim_chars('\n').split_str(",").collect()).collect();

这是我收到的编译器错误消息:

.../src/main.rs:13:18: 13:19 error: `x` does not live long enough
.../src/main.rs:13         .map(|x| x.as_slice().trim_chars('\n').split_str(",").collect()).collect();
                                                             ^
.../src/main.rs:7:11: 21:2 note: reference must be valid for the block at 7:10...
.../src/main.rs:7 fn main() {
.../src/main.rs:8     let path = Path::new("./...");
.../src/main.rs:9     let mut file = BufferedReader::new(File::open(&path));
.../src/main.rs:10     let instances: Vec<Vec<&str>> = file.lines()
.../src/main.rs:11         .map(|x| x.unwrap())
.../src/main.rs:12         .filter(|x| !(x.contains("?")))
                                            ...
.../src/main.rs:13:18: 13:72 note: ...but borrowed value is only valid for the block at 13:17
.../src/main.rs:13         .map(|x| x.as_slice().trim_chars('\n').split_str(",").collect()).collect();

我不明白Rust中字符串类型的生命周期应该如何在此上下文中使用。将instances更改为Vec<Vec<String>>也无法解决问题。

让我感到特别困惑的是,以下是使用单个字符串:

let x: Vec<&str> = some_string.as_slice().trim_chars('\n').split_str(",").collect();

这些值的生命周期导致此编译器错误,我做错了什么?

如果迭代器适配器不是解决此问题的惯用方法,请解释为什么以及如何以不同方式处理它。

1 个答案:

答案 0 :(得分:2)

x &str是对String内容的引用,由lines()产生的内容。 &str只能在String引用时生效,并且您不会将String存储在任何地方。您需要将行存储在另一个变量中:

let lines = file.lines().map(|x| x.unwrap()).collect::<Vec<_>>();
let instances: Vec<Vec<&str>> = lines.iter()
    .filter(|x| !(x.contains("?")))
    .map(|x| x.trim_chars('\n').split_str(",").collect()).collect();

否则您可以将所有&str转换为String s:

let instances: Vec<Vec<String>> = file.lines()
    .map(|x| x.unwrap())
    .filter(|x| !(x.contains("?")))
    .map(|x| x.trim_chars('\n').split_str(",")
        .map(|x| x.into_string()).collect()).collect();

作为附带说明,collect()调用可以写为collect::<Vec<_>>(),允许您从instances变量中删除类型注释。哪个更好?由您决定。