Я очень плохо знаком с Rust и системными языками в целом.И я сейчас играю с Rust, чтобы изучить язык.У меня проблема, которую я не могу решить самостоятельно.И я думаю, что понимаю проблему, которая происходит.
Я не хочу хранить объекты, которые реализуют trait BaseStuff
в векторе.В Rust не простая задача для меня: -).
Вот мой пример кода, который не будет компилироваться.
trait BaseStuff {}
struct MyStuff {
value: i32,
}
struct AwesomeStuff {
value: f32,
text: String,
}
impl BaseStuff for MyStuff {}
impl BaseStuff for AwesomeStuff {}
struct Holder {
stuff: Vec<BaseStuff>,
}
impl Holder {
fn register(&mut self, data: impl BaseStuff) {
self.stuff.push(data);
}
}
fn main() {
let my_stuff = MyStuff { value: 100 };
let awesome_stuff = AwesomeStuff {
value: 100.0,
text: String::from("I'm so awesome!"),
};
let mut holder = Holder { stuff: vec![] };
holder.register(my_stuff);
}
error [E0277]: размер для значенийтипа (dyn BaseStuff + 'static)
невозможно знать во время компиляции -> src \ main.rs: 17: 5 |17 |
материал: Vec, // неизвестный размер |^^^^^^^^^^^^^^^^^^^^^ размер не известен во время компиляции |= help: черта std::marker::Sized
не реализована для (dyn BaseStuff +
'static)
= примечание: чтобы узнать больше, посетите https://doc.rust -lang.org / book / second-edition / ch19-04-advanced-types.html #признак динамических размеров-типов-и-размеров = примечание: требуется std::vec::Vec
ошибка: прерывание из-за предыдущей ошибки
Для получения дополнительной информации об этой ошибке,попробуйте rustc --explain E0277
.ошибка: не удалось скомпилировать playground
.
Сообщение компилятора ясно, и я понимаю сообщение.Я могу реализовать свойство BaseStuff в любой структуре, которую я хочу, поэтому неясно, какой у нее размер.Кстати, ссылка не полезна, потому что она указывает на устаревший сайт ...
Размер String также неизвестен, но String реализует черту std::marker::Sized
, и поэтому Vec<String>
будетработать без проблем.Это правильно?
В книге о ржавчине, которую я читал для типов данных с неизвестным размером, я должен хранить эти данные в куче, а не в стеке.Я изменил свой код следующим образом.
struct Holder {
stuff: Vec<Box<BaseStuff>>,
}
impl Holder {
fn register(&mut self, data: impl BaseStuff) {
self.stuff.push(Box::new(data));
}
}
Теперь я сталкиваюсь с новой проблемой компилятора:
Ошибка [E0310]: тип параметра impl BaseStuff
может не жить долгодостаточно -> src \ main.rs: 22: 25 |21 |fn register (& mut self, data: impl BaseStuff) {|
--------------- help: рассмотрите возможность добавления явной границы времени жизни impl BaseStuff: 'static
... 22 |self.stuff.push (Box :: new (data));
|^^^^^^^^^^^^^^ |примечание: ... чтобы тип impl BaseStuff
соответствовал требуемым границам времени жизни -> src \ main.rs: 22: 25 |22 |self.stuff.push (Box :: new (data));
|^^^^^^^^^^^^^^
ошибка: прерывание из-за предыдущей ошибки
Для получения дополнительной информации об этой ошибке, попробуйте rustc --explain E0310
.ошибка: не удалось скомпилировать playground
.
И знаю, что меня нет ... Я прочитал в книге о времени жизни и много изменил свой код с помощью 'a
здесь и 'a
влюбая комбинация, но без удачи ... Я не хочу записывать любую комбинацию определения жизни, которую я пробовал.Я не понимаю, почему мне нужно определение продолжительности жизни.Владение перемещается на любом этапе, поэтому, насколько я понимаю, ясно, что структура Holder является владельцем всех данных.
Как я могу исправить свой код для компиляции?
Спасибо за помощь.