这个问题已经在这里有一个答案:
如何采取Vec<Option<T>>
,其中T
不能被复制,并解开所有的Some
值?
我碰到的map
一步一个错误。我很高兴地移动原始名单的所有权和“扔掉”的None
s。
#[derive(Debug)]
struct Uncopyable {
val: u64,
}
fn main() {
let num_opts: Vec<Option<Uncopyable>> = vec![
Some(Uncopyable { val: 1 }),
Some(Uncopyable { val: 2 }),
None,
Some(Uncopyable { val: 4 }),
];
let nums: Vec<Uncopyable> = num_opts
.iter()
.filter(|x| x.is_some())
.map(|&x| x.unwrap())
.collect();
println!("nums: {:?}", nums);
}
这给错误
error[E0507]: cannot move out of borrowed content
--> src/main.rs:17:15
|
17 | .map(|&x| x.unwrap())
| ^-
| ||
| |hint: to prevent move, use `ref x` or `ref mut x`
| cannot move out of borrowed content
生锈,当你需要一个值,你通常要移动的元素或克隆它们。
由于此举是更普遍的,在这里it is,只有两个变化是必要的:
let nums: Vec<Uncopyable> = num_opts
.into_iter()
// ^~~~~~~~~~~~-------------- Consume vector, and iterate by value
.filter(|x| x.is_some())
.map(|x| x.unwrap())
// ^~~------------------ Take by value
.collect();
作为qazxsw POI,qazxsw POI是专业已经过滤掉qazxsw POI:
llogiq points out
然后,它的工作原理(消费filter_map
)。
你并不需要在所有复制None
,如果你是使用到原来的let nums: Vec<Uncopyable> = num_opts
.into_iter()
// ^~~~~~~~~~~~-------- Consume vector, and iterate by value
.filter_map(|x| x)
// ^~~----- Take by value
.collect();
引用的num_opts
OK:
Uncopyable
这可能不会做的伎俩你,如果你有需要Vec
API来工作。在这种情况下,使用其Vec
可以简化为:
let nums: Vec<&Uncopyable> = num_opts.iter().filter_map(|x| x.as_ref()).collect();
// ^ notice the & before Uncopyable?