我想在不改变类型的情况下可选地过滤一个切片。以下方法失败:
use std::collections::HashSet;
fn main() {
let include: Option<HashSet<i8>> = Some(HashSet::new());
let y: &[i8] = &[1, 2, 3];
let z: &[i8] = match include {
Some(set) => {
let filtered: Vec<i8> = y.iter().filter(|&i| set.contains(i)).map(|&i| i).collect();
filtered.as_slice()
},
None => y
};
println!("{:?}", z);
}有错误
error: `filtered` does not live long enough
--> <anon>:10:9
|
9 | filtered.as_slice()
| -------- borrow occurs here
10 | },
| ^ `filtered` dropped here while still borrowed
...
14 | }
| - borrowed value needs to live until here-- 游乐场
我理解filtered的生存期不够长,因为切片只是对它的引用。我试图复制、克隆或以其他方式生成结果filtered.as_slice()的静态版本,但没有进行编译。
在filtered定义之外声明z不能工作,因为它需要set进行筛选。
我认为这种转换为迭代器,然后转换为向量,然后转换为切片可能不是惯用的。所以我很想知道一个更好的方法。
发布于 2017-01-05 10:03:25
在z定义之外声明已过滤的内容将无法工作,因为它需要设置来执行筛选。
我不明白为什么不。在语句filtered.as_slice()中,您从filtered那里借用,所以必须确保filtered的寿命比指定给它的变量(z)更长:
use std::collections::HashSet;
fn main() {
let mut h = HashSet::new();
h.insert(2);
let exclude: Option<HashSet<i8>> = Some(h);
let y: &[i8] = &[1, 2, 3];
let filtered: Vec<i8>;
let z: &[i8] = match exclude {
Some(set) => {
filtered = y.iter().filter(|&i| !set.contains(i)).map(|&i| i).collect();
filtered.as_slice()
},
None => y
};
println!("{:?}", z); // outputs [1, 3]
}注:我在filter中倒置了逻辑。
https://stackoverflow.com/questions/41480859
复制相似问题