Невозможно переместить заимствованное содержимое внутри замыкания

Новичок в ржавчине. Я пытаюсь написать функцию, которая использует переданный вектор, изменяет его, добавляет к другому вектору и возвращает.

Вот мой код:

fn try(other: Vec<(String, String)>) -> Vec<(String, String)> {
    let mut res = Vec::new();
    let mut neg: Vec<(String,String)> = other
                                        .iter()
                                        .map(|t| (t.0, String::from("abc")))
                                        .collect();
    res.append(&mut neg);
    res
}

Тем не менее, я получаю cannot move out borrowed content в t.0. Что я делаю не так? Что передается в закрытие?

.iter() возвращает итератор к ссылкам каждого элемента в векторе. Кажется, ты хочешь into_iter().
E_net4 the curator 08.04.2019 14:44

В чем смысл res? Почему бы просто не вернуть neg напрямую?

Mara Bos 08.04.2019 14:49

@ E_net4 Я бы не назвал этот вопрос дубликатом. Этот вопрос, на который вы ссылаетесь, вы бы задали, только если уже знаете, что здесь следует использовать into_iter. Хотя ответ на вопрос весьма актуален. (Кроме того, лучшее решение здесь — вообще не использовать into_iter, а просто изменить исходный вектор и вернуть его.)

Mara Bos 08.04.2019 14:53

@ M-ou-se Это ответ, который действительно важен при выборе дублирующей цели. Если вопрос является дубликатом, это не означает, что целевой вопрос точно такой же, но его ответы также решают эту проблему. Что касается того, является ли это хорошей дублирующей целью или нет, я оставлю решение оставшимся избирателям.

E_net4 the curator 08.04.2019 14:55

большое спасибо. я согласен с комментариями. нужно было знать, что в этом контексте следует использовать into_iter.

pd176 08.04.2019 15:05
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
0
5
150
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

t.0 пытается переехатьString из кортежа, на который ссылается t, но t только заимствует его. Это потому, что .iter() дает вам итератор, который дает вам ссылки на значения. Если вы используете into_iter() вместо iter(), вы получаете потреблять все значения other, а не только их занимать, потому что other.into_iter() потребляет other.

В вашем конкретном примере было бы более эффективно полностью повторно использовать other вместо создания нового Vec с содержимым (частично), взятым из other, а затем удалить other:

fn try2(mut other: Vec<(String, String)>) -> Vec<(String, String)> {
    for x in &mut other {
        x.1 = String::from("abc");
    }
    other
}

Было бы еще эффективнее повторно использовать String вместо того, чтобы создавать новые с помощью String::from.

Чем ваш ответ отличается от предложенного дубликата В чем разница между iter и into_iter??

hellow 08.04.2019 14:53

@hellow Этот вопрос касается только первой части. Показ того, что into_iter() и collect() не лучший вариант в этом случае, является весьма важной частью, которая не рассматривается в этом вопросе/ответе.

Mara Bos 08.04.2019 15:01

Другие вопросы по теме