У меня есть черта Foo
pub trait Foo {
fn do_something(&self) -> f64;
}
и структура, которая ссылается на эту черту
pub struct Bar {
foo: Foo,
}
Пытаясь скомпилировать, я получаю
error: reference to trait `Foo` where a type is expected; try `Box<Foo>` or `&Foo`
Изменение структуры на
struct Bar {
foo: &Foo,
}
Сообщает мне error: missing lifetime specifier
Изменение определения на
struct Bar {
foo: Box<Foo>,
}
Скомпилирует - yay!
Однако, когда я хочу, чтобы функция возвращала Foo
на bar
- что-то вроде:
impl Bar {
fn get_foo(&self) -> Foo {
self.foo
}
}
Ну, очевидно, bar.foo
является Box<Foo>
, поэтому, как я полагаю, я получаю error: reference to trait `Foo` where a type is expected; try `Box<Foo>` or `&Foo`
Изменение подписи на
impl Bar {
fn get_foo(&self) -> Box<Foo> {
let this = *self;
this.foo
}
}
Но теперь я получаю error: cannot move out of dereference of `&`-pointer
при попытке разыменования self
.
Переход на
impl Bar {
fn get_foo(self) -> Box<Foo> {
self.foo
}
}
Все хорошо.
Так....
- Почему в работе
bar
не работает&
? Я предполагаю, что мне нужно вставить поскольку структуры имеют заданный формат памяти, поэтому мы должны сказать, что это указатель к черту (поскольку мы не можем знать, насколько это будет важно), но почему компилятор предлагает что-то, что не компилируется? - Почему я не могу разыменовать
self
вget_foo()
- все примеры, которые я видел, используют заимствованный синтаксисself
? - Что подразумевается при удалении
&
и просто использованииself
?
Обучение ржавчине увлекательно, но безопасность памяти одновременно увлекательна и запугивает!
Код полностью компилируется:
trait Foo {
fn do_something(&self) -> f64;
}
struct Bar {
foo: Box<Foo>,
}
impl Bar {
fn get_foo(self) -> Box<Foo> {
let foo = self.foo;
foo.do_something();
foo
}
}
fn main() {}