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