I have the following code:
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,
}
When I try to compile it I get the error message:
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
I think I know why it happens, but how do I refer to the trait from the struct? Is it possible? Maybe there are other ways to implement the same behavior?
You can either add a type parameter to your struct, as in Zernike's answer, or use a trait object.
Using the type parameter is better for performance because each value of T
will create a specialized copy of the struct, which allows for static dispatch. A trait object uses dynamic dispatch so it lets you swap the concrete type at runtime.
The trait object approach looks like this:
pub struct MyStruct<'a> {
my_trait: &'a MyTrait,
}
Or this:
pub struct MyStruct {
my_trait: Box<MyTrait>,
}
However, in your case, MyStruct
cannot be made into an object because receive
is a static method. You'd need to change it to take &self
or &mut self
as its first argument for this to work. There are also other restrictions.
pub struct MyStruct<T>
where
T: MyTrait,
{
my_trait: T,
}
or
pub struct MyStruct<T: MyTrait> {
my_trait: T,
}
https://doc.rust-lang.org/book/second-edition/ch10-02-traits.html#trait-bounds
There is a fourth option available, but this will make your struct unsized, a.k.a. you will not be able to create instances of this struct.
pub trait MyTrait {}
pub struct MyStruct {
my_trait: MyTrait + 'static,
}
This means that MyStruct
is an unsized type, and you cannot create direct instances of such type. As Rust currently does not have a way to allocate structs directly on the stack, I do not know if you can create an instance of such a type at all. But hey, it compiles.