У меня есть trait Surface: 'static
, который я хочу реализовать для struct Obj<'a>
.Черта должна быть 'static
, потому что я хочу хранить объекты типа Surface
в Vec<Box<Surface>>
.
На первом шаге я попробовал это.
impl<'a> Surface for Obj<'a> {}
Это будетне работает из-за несоответствия времени жизни между 'static
и 'a
.Другими словами: Surface
может жить дольше, чем Obj
, потому что Surface
- это 'static
.Я изменил свою реализацию следующим образом.
impl<'a> Surface for Obj<'a> where 'a: 'static {}
Насколько я правильно понимаю документацию, то, что я делаю, 'a
может пережить 'static
.Хочу ли я это?
Если я передам владение Obj<'a>
, компилятор скажет мне, что изменяемая ссылка внутри Obj
не будет жить достаточно долго и все еще будет заимствована.
Здесьэто короткий пример.
trait Surface: 'static {}
struct Manager {
storage: Vec<Box<Surface>>,
}
impl Manager {
fn add(&mut self, surface: impl Surface) {
self.storage.push(Box::new(surface));
}
}
struct SomeOtherStruct {}
struct Obj<'a> {
data: &'a mut SomeOtherStruct,
}
impl<'a> Obj<'a> {
fn new(some_struct: &'a mut SomeOtherStruct) -> Self {
Obj { data: some_struct }
}
}
impl<'a> Surface for Obj<'a> where 'a: 'static {}
fn main() {
let mut some_struct = SomeOtherStruct {};
let mut manager = Manager {
storage: Vec::new(),
};
let obj = Obj::new(&mut some_struct);
manager.add(obj);
}
( Детская площадка )
error[E0597]: `some_struct` does not live long enough
--> src/main.rs:33:24
|
33 | let obj = Obj::new(&mut some_struct);
| ---------^^^^^^^^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `some_struct` is borrowed for `'static`
34 | manager.add(obj);
35 | }
| - `some_struct` dropped here while still borrowed
Другими словами &mut some_struct
- это время жизни 'a
, но требуется 'static
.Хорошо, это понятно, потому что some_struct
живет в Obj<'a>
, поэтому это не может быть 'static
?
Это то, что я пытаюсь сделать "Rust like"?Я понятия не имею, как заставить это работать.Это действительно путает с жизнями.Я думаю, что могу обойти это, используя Rc<T>
, но это усложнит ситуацию.