Вопрос или проблема
Я хочу расширить/добавить к 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"]
}
Пояснение:
-
Инициализация вектора: В вашем примере функция
init()
создаёт вектор строк. Вы можете использоватьto_string()
вместоmap(|s| s.to_owned())
, чтобы упростить код. -
Добавление строки: После инициализации вектора вы создаёте новую строку
next_string
. Чтобы добавить её в векторres
, достаточно вызватьres.push(next_string)
. Не нужно присваиватьres
результат вызоваpush
, так как он возвращает()
.
Теперь, когда вы запустите этот код, вывод будет корректным:
res: ["string one"]
res: ["string one", "string two"]
Это именно то, что вы и желали получить. Вы правильно находитесь на пути изучения Rust, и такие ошибки — это нормальная часть процесса обучения. Если у вас есть дополнительные вопросы, не стесняйтесь задавать!