web-dev-qa-db-fra.com

Le trait ne peut pas être transformé en objet

J'ai le code suivant:

extern crate futures; // 0.1.24

use futures::Future;
use std::io;

struct Context;

pub trait MyTrait {
    fn receive(context: Context) -> Future<Item = (), Error = io::Error>;
}

pub struct MyStruct {
    my_trait: MyTrait,
}

Lorsque j'essaie de le compiler, je reçois le message d'erreur suivant: 

error[E0038]: the trait `MyTrait` cannot be made into an object
  --> src/lib.rs:13:5
   |
13 |     my_trait: MyTrait,
   |     ^^^^^^^^^^^^^^^^^ the trait `MyTrait` cannot be made into an object
   |
   = note: method `receive` has no receiver

Je pense savoir pourquoi cela se produit, mais comment puis-je me référer au trait de la structure? C'est possible? Peut-être y a-t-il d'autres moyens d'implémenter le même comportement?

9
Alexander

Vous pouvez soit ajouter un paramètre de type à votre structure, comme dans la réponse de Zernike , ou utiliser un objet trait. 

L'utilisation du paramètre type est préférable pour les performances car chaque valeur de T créera une copie spécialisée de la structure, ce qui permet une répartition statique. Un objet trait utilise la répartition dynamique pour vous permettre d’échanger le type concret au moment de l’exécution.

L'approche objet trait ressemble à ceci:

pub struct MyStruct<'a> {
    my_trait: &'a MyTrait,
}

Ou ca:

pub struct MyStruct {
    my_trait: Box<MyTrait>,
}

Cependant, dans votre cas, MyStruct ne peut pas être transformé en objet car receive est une méthode statique. Pour que cela fonctionne, vous devez le changer pour que &self ou &mut self soit le premier. Il y a aussi autres restrictions .

12
Peter Hall
pub struct MyStruct<T>
where
    T: MyTrait,
{
    my_trait: T,
}

ou

pub struct MyStruct<T: MyTrait> {
    my_trait: T,
}

https://doc.Rust-lang.org/book/second-edition/ch10-02-traits.html#trait-bounds

4
Zernike

Une quatrième option est disponible, mais cela rendra votre structure non dimensionnée, a.k.a. vous ne pourrez pas créer d’occurrences de cette structure.

pub trait MyTrait {}

pub struct MyStruct {
    my_trait: MyTrait + 'static,
}

Cela signifie que MyStruct est un type non dimensionné et vous ne pouvez pas créer d'instances directes de ce type. Comme Rust ne dispose actuellement d'aucun moyen pour allouer des structures directement sur la pile, je ne sais pas si vous pouvez créer une instance d'un tel type. Mais bon, ça compile .

0
Hauleth