我怎样才能获得 Vec 元素的所有权并将其替换为其他元素?

How can I take ownership of a Vec element and replace it with something else?

我正在编写以下格式的函数:

fn pop<T>(data: &mut Vec<Option<T>>) -> Option<T> {
    // Let the item be the current element at head
    let item = data[0];

    // and "remove" it.
    data[0] = None;

    item
}

当我尝试执行此操作时,出现了一个有意义的错误:

error[E0507]: cannot move out of index of `std::vec::Vec<std::option::Option<T>>`
 --> src/lib.rs:3:16
  |
3 |     let item = data[0];
  |                ^^^^^^^ move occurs because value has type `std::option::Option<T>`, which does not implement the `Copy` trait
  |
help: consider borrowing the `Option`'s content
  |
3 |     let item = data[0].as_ref();
  |                ^^^^^^^^^^^^^^^^
help: consider borrowing here
  |
3 |     let item = &data[0];
  |                ^^^^^^^^

当我尝试更改它以使 item 成为参考时,当我尝试将 data[0] 设置为 None 时出现错误,这也是有道理的。

有什么方法可以做我想做的事吗?在我看来,无论我是否想要 return 引用,我都必须从 Vec 中获取元素的所有权。

我注意到 Vec 有一个 swap_remove 方法,它几乎完全符合我的要求,只是它与 Vec 中已有的元素交换,而不是与任何任意元素交换我想要的价值。我知道我可以将 None 附加到 Vec 的末尾并使用 swap_remove,但我想看看是否有其他方法。

使用std::mem::replace:

use std::mem;

fn pop<T>(data: &mut Vec<Option<T>>) -> Option<T> {
    mem::replace(&mut data[0], None)
}

replace 本质上是将特定位置的值替换为另一个值和 returns 之前的值。

另请参阅:

  • How can I swap in a new value for a field in a mutable reference to a structure?