Невозможно выйти из заимствованного содержимого при использовании синтаксиса обновления struct literal: User {active: false, .. * user} - PullRequest
0 голосов
/ 05 мая 2018

Я начинаю с Rust, и мне очень нравится синтаксис с .. до , создающий экземпляр другого экземпляра , но я не знаю, как использовать его со ссылкой на экземпляр вместо .

Попробуйте здесь.

#[derive(Debug)]
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

fn main() {
    let user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
    let user2 = foo(&user1);

    println!("{:?}", user2);
}

fn foo(user: &User) -> User {
    User {
        active: false,
        ..*user
    }
}

Что дает мне ошибку:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:24:11
   |
24 |         ..*user
   |           ^^^^^ cannot move out of borrowed content

Самое смешное, что в какой-то момент это сработало для меня:

fn reduce<'a>(state: &State<'a>, action: Action) -> Option<State<'a>> {
    match action {
        Action::LoadRoms { roms } => {
            let mut new_state = State { roms, ..*state };
            Some(new_state)
        }
        _ => None,
    }
}

Отсюда.

1 Ответ

0 голосов
/ 05 мая 2018

Синтаксис ..expr перемещает все отсутствующие элементы из expr. Это движется . Это означает, что вы, как правило, не можете использовать его со ссылкой, поскольку вы не можете выйти из ссылки (хотя вы можете «переместить» Copy типов из ссылки).

Чтобы решить вашу проблему, вам нужно клонировать, чтобы получить новый полный объект, с которого вы можете перейти:

fn foo(user: &User) -> User {
    User {
        active: false,
        ..user.clone()
    }
}

( ссылка на игровую площадку )

Недостатком является то, что это также клонирует всех членов, которые вам не нужны, потому что вы уже указали их. В этом случае это нормально, так как клонирование active является тривиальной операцией (поскольку это просто логическое значение), однако это сделает дополнительный бесполезный клон для username:

fn foo(user: &User) -> User {
    User {
        username: "foo".into(),
        ..user.clone()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...