有没有一种方法可以将数组中多个非复制元素移出?

4
有没有办法像 [a,b] = map 这样分解数组,让这两个数组元素分别移动到 ab 中,以便稍后可以将 ab 移动到另一个函数中(比如在这种情况下的 printme 函数)。
enum Direction {
    North,
    East,
    South,
    West,
}

struct RoadPoint {
    direction: Direction,
    index: i32,
}

fn printme(a: RoadPoint, b: RoadPoint) {
    println!("First: {}", a.index);
}

fn main() {
    let mut map: [RoadPoint; 2] = [
        RoadPoint {
            direction: Direction::North,
            index: 0,
        },
        RoadPoint {
            direction: Direction::North,
            index: 0,
        },
    ];

    for i in 1..3 {
        map[i].index = 10;
    }

    //move out
    printme(map[0], map[1])
}

error[E0508]: cannot move out of type `[RoadPoint; 2]`, a non-copy array
  --> src/main.rs:34:13
   |
34 |     printme(map[0], map[1])
   |             ^^^^^^ cannot move out of here

error[E0508]: cannot move out of type `[RoadPoint; 2]`, a non-copy array
  --> src/main.rs:34:21
   |
34 |     printme(map[0], map[1])
   |                     ^^^^^^ cannot move out of here

我知道我可以实现Copy特征,但在这种情况下我实际上不需要数据的副本。因此,我正在寻找更简洁的解决方案。


你的一些代码不太符合惯用法:建议直接迭代集合而不是使用索引范围(for point in &mut map { })。 - E net4
1个回答

2

如果使用带有非词法生命周期特性和固定长度切片模式的夜间版 Rust,您可以使其正常工作:

#![feature(nll)]

enum Direction {
    North,
    East,
    South,
    West,
}

struct RoadPoint {
    direction: Direction,
    index: i32,
}

fn printme(a: RoadPoint, b: RoadPoint) {
    println!("First: {}", a.index);
    println!("Second: {}", b.index);
}

fn main() {
    let map: [RoadPoint; 2] = [
        RoadPoint {
            direction: Direction::North,
            index: 0,
        },
        RoadPoint {
            direction: Direction::North,
            index: 0,
        },
    ];

    let [a, b] = map;
    printme(a, b);
}

如果没有#![feature(nll)],它将会失败:

error[E0382]: use of moved value: `map[..]`
  --> src/main.rs:30:13
   |
30 |     let [a, b] = map;
   |          -  ^ value used here after move
   |          |
   |          value moved here
   |
   = note: move occurs because `map[..]` has type `RoadPoint`, which does not implement the `Copy` trait

非常感谢,这正是我正在寻找的。 - Stefan
在 Rust 中,非 Copy 类型的数组不是很灵活。也许你可以像这样做:let mut v: Vec<_> = (Box::new(map) as Box<[_]>).into(); let b = v.pop().unwrap(); let a = v.pop().unwrap();。但如果你本来就使用 Vec 而不是数组,那么这些都不需要考虑! - rodrigo
是的,我可能会选择使用Vec和pop()。 这意味着数据存储在堆上。由此是否存在任何性能影响? - Stefan
对于一个稳定版本,您可以查看split_at - hellow
@hellow:但是split_at适用于切片,而不是数组,也就是说,它们返回的是借用引用。OP要求一种将值从数组中移出的方法。 - rodrigo
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接