У меня есть структура с полем:

struct A {
    field: SomeType,
}

Учитывая &mut A, как я могу переместить значение field и заменить новое значение?

fn foo(a: &mut A) {
    let mut my_local_var = a.field;
    a.field = SomeType::new();

    // ...
    // do things with my_local_var
    // some operations may modify the NEW field's value as well.
}

Конечная цель будет эквивалентом операции get_and_set(). В данном случае меня не беспокоит параллелизм.

45
arcyqwerty 24 Ноя 2014 в 08:58

2 ответа

Лучший ответ

Используйте std::mem::swap().

fn foo(a: &mut A) {
    let mut my_local_var = SomeType::new();
    mem::swap(&mut a.field, &mut my_local_var);
}

Или std::mem::replace().

fn foo(a: &mut A) {
    let mut my_local_var = mem::replace(&mut a.field, SomeType::new());
}    
55
Shepmaster 16 Мар 2020 в 22:44
10
Или let mut my_local_var = mem::replace(&mut a.field, SomeType::new());. Эти два точно эквивалентны.
 – 
Chris Morgan
24 Ноя 2014 в 09:25

Если ваш тип реализует Default, вы можете использовать std::mem::take:

#[derive(Default)]
struct SomeType;

fn foo(a: &mut A) {
    let mut my_local_var = std::mem::take(&mut a.field);
}

Если ваше поле имеет вид Option, вы можете использовать специальный метод — Option::take:

struct A {
    field: Option<SomeType>,
}

fn foo(a: &mut A) {
    let old = a.field.take();
    // a.field is now None, old is whatever a.field used to be
}

реализация Option::take использует mem::take, как показано в более общем ответе выше, но он красиво упакован для вас:

pub fn take(&mut self) -> Option<T> {
    mem::take(self)
}

Смотрите также:

31
Shepmaster 4 Июн 2021 в 23:53