Извините за неопределенный заголовок, но я довольно новичок в Rust, поэтому я точно не знаю, как кратко подвести итог моей проблеме.
Я пытаюсь реализовать что-то, что (показывая минимальный пример) выглядит следующим образом:
trait Bar<T> {}
struct Foo<T> {
data: Vec<Box<Bar<T>>>
}
impl<T> Foo<T> {
fn add<U: Bar<T>>(&mut self, x: U) {
self.data.push(Box::new(x));
}
}
Так как Rust по умолчанию (насколько я могу судить, по-русски), моя ментальная модель думает, что это должно работать. Метод add принимает собственность на объект x
, а затем способен переместить этот объект в Box
, потому что он знает полный тип U
(а не только символ Bar<T>
). Когда он перемещается в ящик, время жизни элемента внутри поля должно быть привязано к фактическому времени жизни блока (например, когда pop()
отброшен вектор, объект будет уничтожен).
Ясно, однако, что компилятор не согласен (и я уверен, что знает немного больше, чем я...), прося меня рассмотреть вопрос о добавлении классификатора времени жизни 'static
(E0310). Я на 99% уверен, что не то, что хочу, но я не совсем уверен, что я должен делать.
Чтобы прояснить, что я думаю, и помочь определить неправильные представления, моя модель по существу (я исхожу из фона С++):
-
Box<T>
по существуstd::unique_ptr<T>
- Без каких-либо аннотаций переменные передаются по значению, если
Copy
и rvalue-reference в противном случае - Со ссылкой на аннотацию
&
примерноconst&
и&mut
примерно&
- Время жизни по умолчанию - лексическая область