首页 文章

特征不能成为一个对象

提问于
浏览
9

我有以下代码:

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

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

3 回答

  • 12

    您可以在结构中添加类型参数,如Zernike's answer,也可以使用特征对象 .

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

    特征对象方法如下所示:

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

    或这个:

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

    但是,在您的情况下, MyStruct 无法成为对象,因为 receive 是静态方法 . 您需要将其更改为 &self&mut self 作为其工作的第一个参数 . 还有other restrictions .

  • 4
    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

  • 0

    有第四个选项可用,但这会使你的结构不合格,a.k.a . 你将无法创建这个结构的实例 .

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

    这意味着 MyStruct 是一个unsized类型,您无法创建此类型的直接实例 . 由于Rust目前没有办法直接在堆栈上分配结构,我不知道你是否可以创建这种类型的实例 . 但是,嘿,it compiles .

相关问题