Rust 为什么编译器需要这个特性提示?

Rust 为什么编译器需要这个特性提示?,rust,traits,Rust,Traits,我有这个密码: pub trait MiddlewareHandler: Clone + Send { //...probably unimportant for the question } #[deriving(Clone)] pub struct Middleware { handlers: Vec<Box<MiddlewareHandler>> } #[deriving(Clone)] pub struct Server{ middle

我有这个密码:

pub trait MiddlewareHandler: Clone + Send {
    //...probably unimportant for the question
}

#[deriving(Clone)]
pub struct Middleware {
    handlers: Vec<Box<MiddlewareHandler>>
}

#[deriving(Clone)]
pub struct Server{
    middleware: Middleware
}
我花了很长时间才意识到我必须将
Vec
更改为
Vec
,以便最终的代码如下所示:

pub trait MiddlewareHandler: Clone + Send {
    //...probably unimportant for the question
}

#[deriving(Clone)]
pub struct Middleware {
    handlers: Vec<Box<MiddlewareHandler + Send>>
}

#[deriving(Clone)]
pub struct Server{
    middleware: Middleware
}
public仓库管理员:克隆+发送{
//…对这个问题来说可能不重要
}
#[衍生(克隆)]
发布结构中间件{
处理程序:Vec
}
#[衍生(克隆)]
发布结构服务器{
中间件:中间件
}
代码现在可以编译了,但我不明白这里到底是什么问题。为什么在
Vec
定义中
+Send
?我的意思是,
MiddlewareHandler
trait已经实现了
Send+Clone
。在我看来这是多余的

有人能告诉我为什么我要这样修改代码吗?

似乎是个bug,我提出了


“问题”是
http::server::server
上的
Send
限制。定义是

pub trait Server: Send + Clone {
这意味着被实施者需要既是
克隆
(这很满意,因为您已经通过
#[派生(克隆)]
实现了
克隆
)又是
发送
。对于内容满足
Send
的类型,编译器会自动实现
Send
(此细节将随而变化:它们也需要显式实现),不幸的是,原始类型类似于

pub struct Middleware {
    handlers: Vec<Box<Trait>>
}
pub结构中间件{
处理程序:Vec
}
通常不实现
Send
:编译器无法知道
中已擦除的类型是
Send
可执行的,例如,它可能包含一个
Rc
,因此转移到不同的任务是不安全的

编译器需要知道更多信息,也就是说,它需要保证内部类型是
Send
,这可以通过向trait对象添加更多边界来提供:
Box


然而,在这种情况下,
MiddlewareHandler
trait已经将这个
Send
绑定为一个超级trait(这意味着trait对象的内容必须满足
Send
),因此编译器没有计算出
Send
(因此提交了错误).

错误消息指向
server::server
特征?它的定义是什么?
server
struct就是这个示例中概述的结构,我也对它进行了一些简化。这是这样的:
http::server::server
trait的定义是:我对trait感兴趣,而不是结构,因为它在错误消息中。:)没有涉及其他
服务器
特性
server::server
server
结构。
impl http::server::server for server
是一种特性。编译器不能将所有实现的特性添加到
MiddlewareHandler
本身的所有用法中吗?如果编译器可以方便地查找
MiddlewareHandler
特征并在使用
MiddlewareHandler
的任何地方添加
Clone+Send
(在本例中),Rust为什么要我手动执行此操作?我的意思是,这甚至可以作为预编译步骤添加,不是吗?我可能过于简单化了,但对我来说,规则似乎很简单:添加
MiddlewareHandler
的所有实现特征,因此在本例中,
Clone+Send
到使用
MiddlewareHandler
的所有位置。在本例中,位于
Vec
。因此,预编译步骤可以自动将
Vec
转换为
Vec
。否?是的,它可以做到这一点,但目前的行为是一个错误;没有押韵也没有理由,只是意外地实现了。也许您描述的是修复(但是,不可能使用预编译步骤,除非您使用脚本来编辑文件).我只是有点困惑,因为一方面你同意这是一个bug,但在你编写的同时,编译器无法知道
中删除的类型是可发送的。我可能不得不更经常地重读这篇文章。我真的很感谢你花这么多时间帮助我开始生锈。“我希望我能还给你一些东西。”克里斯托夫,哦,对不起,我是说一件普通的物品。我会澄清的。
pub struct Middleware {
    handlers: Vec<Box<Trait>>
}