【问题标题】:How can I take ownership of a Vec element and replace it with something else?如何获得 Vec 元素的所有权并将其替换为其他元素?
【发布时间】:2016-01-17 04:50:00
【问题描述】:

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

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 时出现错误,这也是有道理的。

有什么方法可以做我想做的事吗?在我看来,无论我是否想返回一个引用,我都必须从 Vec 获得元素的所有权。

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

【问题讨论】:

    标签: vector rust lifetime ownership


    【解决方案1】:

    使用std::mem::replace:

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

    replace 实质上是将特定位置的值替换为另一个值并返回之前的值。

    另见:

    【讨论】:

    • 顺便说一句,为了用None 替换可选值,Option 上有一个特殊的方法,称为take()。我会说在适用的情况下使用它而不是 replace() 会更惯用。
    • 我不敢相信 vec 本身没有方法
    猜你喜欢
    • 2018-05-07
    • 2020-03-29
    • 2015-11-11
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多