Ich habe eine Eigenschaft Foo
pub trait Foo {
fn do_something(&self) -> f64;
}
und eine Struktur, die auf dieses Merkmal verweist
pub struct Bar {
foo: Foo,
}
Beim Versuch zu kompilieren bekomme ich
error: reference to trait `Foo` where a type is expected; try `Box<Foo>` or `&Foo`
Ändern der Struktur in
struct Bar {
foo: &Foo,
}
Sagt mir error: missing lifetime specifier
Ändern der Definition in
struct Bar {
foo: Box<Foo>,
}
Kompiliert - yay!
Wenn ich jedoch möchte, dass eine Funktion wieder foo
aktiviert wird bar
- so etwas wie:
impl Bar {
fn get_foo(&self) -> Foo {
self.foo
}
}
Na offensichtlich bar.foo
ist ein Box<Foo>
, so erwartungsgemäß bekomme icherror: reference to trait `Foo` where a type is expected; try `Box<Foo>` or `&Foo`
Ändern der Signatur in
impl Bar {
fn get_foo(&self) -> Box<Foo> {
let this = *self;
this.foo
}
}
Aber jetzt error: cannot move out of dereference of `&`-pointer
versuche ich zu dereferenzieren self
.
Wechseln zu
impl Bar {
fn get_foo(self) -> Box<Foo> {
self.foo
}
}
Ist alles gut.
Damit....
- Warum nicht
&
in derbar
Struktur nicht? Ich gehe davon aus, dass ich boxen muss, da Strukturen ein festgelegtes Speicherlayout haben, also müssen wir sagen, dass es ein Zeiger auf ein Merkmal ist (da wir nicht wissen können, wie groß das sein wird), aber warum schlägt der Compiler etwas vor, das nicht kompiliert werden kann ? - Warum kann ich nicht dereferenzieren
self
inget_foo()
- Alle Beispiele habe ich Gebrauch , den geliehenen gesehenself
Syntax? - Was bedeutet es, das zu entfernen
&
und nur zu verwendenself
?
Rust zu lernen ist faszinierend, aber die Gedächtnissicherheit ist sowohl faszinierend als auch einschüchternd!
Vollständiger Code, der kompiliert:
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() {}
foo: &'a Foo
undfoo: Box<Foo>
. Was erklärt diese Änderungen?Zur späteren Bezugnahme zu beachten: Die Syntax hat sich von geändert
struct Bar<'a> { foo: &'a Foo + 'a, }
zu
struct Bar<'a> { foo: &'a (Foo + 'a), // with parens }
Gemäß RFC 438
quelle