Как избежать заимствования значения, которое было перемещено в замыкание, без использования клона? - PullRequest
2 голосов
/ 07 мая 2019

Я пытаюсь понять замыкания в Rust. Я написал такой код;

use std::ops::Add;

fn main() {
    let mut a = "a string".to_string();

    let mut cl = ||  {
        a.add(" another string");
    };

    cl();

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

Я ожидаю такой результат, как "строка другая строка". В документации говорится, что старайтесь избегать использования clone(), где это возможно, но мне не удается скомпилировать этот код без использования a = a.clone().add(" another string").

Ответы [ 2 ]

2 голосов
/ 07 мая 2019

Чтобы ответить на ваш оригинальный вопрос: Вы не можете.Это потому, что ваша строка a перемещена в замыкание.Вы не можете получить его обратно. См. Денис ответ для решения.


Решением этой конкретной проблемы будет использование push_str вместо Add, потому что push_str требует изменяемой ссылки вместо перемещенного значения.

fn main() {
    let mut a = "a string".to_string();

    let mut cl = || {
        a.push_str(" another string");
    };

    cl();

    println!("{:?}", a);
}
1 голос
/ 07 мая 2019

Решением было бы переместить значение в замыкание, а затем заставить его вернуть его:

use std::ops::Add;

fn main() {
    let mut a = "a string".to_string();
    let cl = ||  {
        a.add(" another string")
    };
    a = cl();
    println!("{:?}", a);
}

Но захват внешней области довольно ограничен.Например, нельзя определить два замыкания таким образом.Возможно, вы захотите более гибкое решение:

let a = "a string".to_string();
let c1 = |s: String|  {
    s.add(" another string")
};
let c2 = |s: String|  {
    s + " and another one"
};
let a = c1(a);
let a = c2(a);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...