如何转换选项的列表 以T的名单时,T不能被复制? [重复]

问题描述 投票:5回答:2

如何采取Vec<Option<T>>,其中T不能被复制,并解开所有的Some值?

我碰到的map一步一个错误。我很高兴地移动原始名单的所有权和“扔掉”的Nones。

#[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);
}

Playground

这给错误

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
iterator rust optional
2个回答
5
投票

生锈,当你需要一个值,你通常要移动的元素或克隆它们。

由于此举是更普遍的,在这里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)。


3
投票

你并不需要在所有复制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?
© www.soinside.com 2019 - 2024. All rights reserved.