Как я могу расширить/добавить элементы в Vec?

Вопрос или проблема

Я хочу расширить/добавить к Vec<String>, что, казалось бы, должно быть легко, но я только запутываюсь, пытаясь заставить это работать. У меня есть:

fn main() {
    // Вспомогательная функция
    fn init () -> Vec<String> {
        vec!["строка одна"].into_iter().map(|s| s.to_owned()).collect()
    }

    let mut res = init();
    println!("res: {:?}", res); // пока все в порядке
    let next_string = String::from("строка две");
    res = res.push(next_string);
    println!("res: {:?}", res);
}

Вывод, который я хочу получить, это ["строка одна", "строка две"], но я получаю ошибку несоответствия типов:

error[E0308]: несоответствие типов
  --> src/main.rs:10:11
   |
7  |     let mut res = init();
   |                   ------ ожидается из-за этого значения
...
10 |     res = res.push(next_string);
   |           ^^^^^^^^^^^^^^^^^^^^^ ожидается `Vec<String>`, найдено `()`
   |
   = примечание: ожидается структура `Vec<String>`
           найден тип единицы `()`
примечание: метод `push` изменяет свой получатель на месте
  --> src/main.rs:10:15
   |
10 |     res = res.push(next_string);
   |           --- ^^^^ этот вызов изменяет `res` на месте
   |           |
   |           вероятно, вы хотите использовать это значение после вызова метода...
   = примечание: ...вместо `()` вывода метода `push`

Я новичок в Rust, так что это может быть что-то глупое или основное непонимание! Примеры в документации касаются целых чисел, а не String, поэтому мне трудно разобраться с этим.

Ответ или решение

Ваша ошибка связана с тем, что метод push в Rust изменяет вектор на месте и не возвращает новое значение. Вместо этого он возвращает тип (), что и вызывает ошибку компиляции.

Для того чтобы правильно добавить элемент в вектор, вам просто нужно вызвать метод push без попытки присвоить его результат переменной res. Вот как это можно исправить:

fn main() {
    // Вспомогательная функция
    fn init() -> Vec<String> {
        vec!["string one".to_string()]
    }

    let mut res = init();
    println!("res: {:?}", res); // до добавления нового элемента

    let next_string = String::from("string two");
    res.push(next_string); // просто вызываем push, не присваиваем результат

    println!("res: {:?}", res); // теперь должны увидеть ["string one", "string two"]
}

Пояснение:

  1. Инициализация вектора: В вашем примере функция init() создаёт вектор строк. Вы можете использовать to_string() вместо map(|s| s.to_owned()), чтобы упростить код.

  2. Добавление строки: После инициализации вектора вы создаёте новую строку next_string. Чтобы добавить её в вектор res, достаточно вызвать res.push(next_string). Не нужно присваивать res результат вызова push, так как он возвращает ().

Теперь, когда вы запустите этот код, вывод будет корректным:

res: ["string one"]
res: ["string one", "string two"]

Это именно то, что вы и желали получить. Вы правильно находитесь на пути изучения Rust, и такие ошибки — это нормальная часть процесса обучения. Если у вас есть дополнительные вопросы, не стесняйтесь задавать!

Оцените материал
Добавить комментарий

Капча загружается...