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

Rust 生锈字符串生存期和迭代器适配器(生存期编译错误),rust,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(); 我

我正在使用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();
我在这些值的生命周期中犯了什么错误导致了这个编译器错误


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

x
&str
是对
字符串
内容的引用,该字符串由
lines()
生成。
&str
只能在
字符串
作为引用时存在,并且您不能将
字符串
存储在任何位置。您需要将行存储在另一个变量中:

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();

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

哦,哇,我尝试了嵌套映射方式,但使用了“to_string”而不是“into_string”…哎哟。这两种方法在性能/内存使用方面是否有差异?具体地说,第一个是否会因为在执行其他操作之前存储未包装的行而消耗整个集合两次?谢谢
to_string
into_string
都可以正常工作,并且在语义上是等价的;然而,就目前而言,
到_string
的效率不如
到_string
,因为它使用了
std::fmt
体系结构,该体系结构目前正在过度分配,而不是尽可能精确,最小分配为128字节,而
到_string
则跳过该体系结构,并且是精确的。我希望
to_string
将来会被修复,但我不确定。如果你想读取CSV数据,那么你应该使用合适的解析器。:)@BurntSushi5:特别是因为在
上拆分,
而不考虑
是个坏主意。。。
let x: Vec<&str> = some_string.as_slice().trim_chars('\n').split_str(",").collect();
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();
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();