Les références à des traits dans les structures

J'ai un trait Foo

pub trait Foo {
   fn do_something(&self) -> f64;
}

et une structure qui de références que le trait

pub struct Bar {
   foo: Foo,
}

En essayant de compiler je obtenir

error: reference to trait `Foo` where a type is expected; try `Box<Foo>` or `&Foo`

La modification de la structure de

struct Bar {
   foo: &Foo,
}

Me dit error: missing lifetime specifier

De changer la définition

struct Bar {
   foo: Box<Foo>,
}

Compile — yay!

Cependant, quand je veux une fonction pour retourner foo sur bar - quelque chose comme:

impl Bar {
    fn get_foo(&self) -> Foo {
        self.foo
    }
}

Bien évidemment bar.foo est un Box<Foo>, donc évidemment je obtenir error: reference to trait `Foo` where a type is expected; try `Box<Foo>` or `&Foo`

La modification de la signature de

impl Bar {
    fn get_foo(&self) -> Box<Foo> {
        let this = *self;
        this.foo
    }
}

Mais maintenant je reçois error: cannot move out of dereference of `&`-pointer à essayer de déréférencer self.

Changer de

impl Bar {
    fn get_foo(self) -> Box<Foo> {
        self.foo
    }
}

Est tout bon.

Donc....

  1. Pourquoi ne pas & dans le bar struct travail? Je suis en supposant que j'ai à la boîte
    structs avoir une set-disposition de la mémoire nous avons donc dire que c'est un pointeur
    à un trait (que nous ne pouvons pas savoir comment grand que sera), mais pourquoi ne l'
    compilateur de proposer quelque chose que l'habitude de compiler?
  2. Pourquoi ne puis-je pas déréférencer self dans get_foo() - Tous les exemples que j'ai vu utiliser le empruntés self syntaxe?
  3. Quelle est l'implication de la suppression de la & et seulement à l'aide de self?

L'apprentissage de la Rouille qui est fascinant, mais la mémoire de la sécurité est à la fois fascinant et intimidant!

Code de la totalité de la compile:

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() {}
InformationsquelleAutor neil danson | 2014-10-06