33

我有以下代码:

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,
}

当我尝试编译它时,我收到错误消息:

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

我想我知道它为什么会发生,但是我如何从结构中引用特征呢?可能吗?也许还有其他方法可以实现相同的行为?

4

3 回答 3

32

您可以将类型参数添加到您的结构中,如Zernike 的 answer中那样,或者使用 trait 对象。

使用 type 参数对性能更好,因为 的每个值都T将创建结构的专用副本,从而允许静态调度。特征对象使用动态调度,因此它允许您在运行时交换具体类型。

特征对象方法如下所示:

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

或这个:

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

但是,在您的情况下,MyStruct不能将其制成对象,因为receive它是静态方法。您需要将其更改为采用&self&mut self作为其第一个参数才能使其正常工作。还有其他限制

于 2017-07-15T12:48:36.560 回答
14
pub struct MyStruct<T>
where
    T: MyTrait,
{
    my_trait: T,
}

或者

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

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

于 2017-07-15T10:18:48.397 回答
0

还有第四个选项可用,但这会使你的结构变小,也就是你不能创建这个结构的实例。

pub trait MyTrait {}

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

这意味着这MyStruct是一个未调整大小的类型,您不能创建这种类型的直接实例。由于 Rust 目前没有办法直接在堆栈上分配结构,我不知道你是否可以创建这种类型的实例。但是,嘿,它编译

于 2018-09-18T18:52:09.270 回答