此代码:
trait Trait {}
fn dont_require_send(ts: Vec<Box<dyn Trait>>) {}
fn use_send(ts: Vec<Box<dyn Trait + Send>>) {
dont_require_send(ts)
}
失败:
error[E0308]: mismatched types
--> src/main.rs:6:23
|
6 | dont_require_send(ts)
| ^^ expected trait `Trait`, found trait `Trait + std::marker::Send`
|
= note: expected type `std::vec::Vec<std::boxed::Box<Trait + 'static>>`
found type `std::vec::Vec<std::boxed::Box<Trait + std::marker::Send + 'static>>`
我有点理解Rust认为Trait
和Trait + Send
是不同的类型,这可能是导致错误的原因。另一方面,我想不出为什么拒绝此特定代码实际上有用的任何原因。实际上,这很烦人,它迫使我在Send
函数的参数中要求dont_require_send
,即使该函数实际上并不需要它。在某些情况下,甚至可能使我为这些标记特征的不同组合实现dont_require_send
的多个版本。
有什么解决方法吗?还是Rust编译器本身有任何计划使该代码编译?
我从评论中提取的内容:这个问题与Is there any way to convert Box> to Box>?相同。两种方式都建议在这里解决我的问题。
fn dont_require_send<U: Trait + ?Sized>(ts: Vec<Box<dyn U>>) {}
的来源,那么dont_require_send
可能是最好的解决方案。我个人不喜欢原来的意图被遮盖,所以我可能很少使用这种新用法。ts.into_iter().map(|t| t as Box<Trait>).collect();
。请注意,仅仅天真地使用另一个问题中的装箱开箱把戏是行不通的(为什么?):dont_require_send(ts.into_iter().map(|t| Box::new(*t)).collect())