[英]Allow trait object creation with user-defined type?
在 Rust 中,引用以及Box<T>
、 Rc<T>
和Arc<T>
允许创建特征对象(例如,从Box<Type>
到Box<dyn Trait>
)。 但是有没有办法允许使用用户定义的通用“智能指针”类型进行相同的转换?
例如, MyBox<T>
是Box<T>
的瘦包装器,但下面的代码会导致编译错误:
use std::io::Write;
pub fn main() {
let std_box: Box<Vec<u8>> = Box::new(Vec::new());
let std_dyn: Box<dyn Write> = std_box;
// ^ this conversion is allowed.
let my_box: MyBox<Vec<u8>> = MyBox { t: Box::new(Vec::new()) };
let my_dyn: MyBox<dyn Write> = my_box;
// ^ this conversion is not allowed.
}
struct MyBox<T: ?Sized> {
t: Box<T>,
}
error[E0308]: mismatched types
--> traits/src/trait_objs.rs:7:36
|
7 | let my_dyn: MyBox<dyn Write> = my_box;
| ---------------- ^^^^^^ expected trait object `dyn std::io::Write`, found struct `Vec`
| |
| expected due to this
|
= note: expected struct `MyBox<dyn std::io::Write>`
found struct `MyBox<Vec<u8>>`
不幸的是,对于 Rust Stable 来说,答案似乎是“你不知道”。 Rust 非常保守,它允许隐式强制转换。 特别是,从docs ,我们看到了Box
的规则。
以下类型之间允许强制转换:
...
TyCtor(
T
) 到 TyCtor(U
),其中 TyCtor(T
) 是其中之一
&T
&mut T
*const T
*mut T
Box<T>
并且其中
U
可以通过无大小强制从T
获得。
其中相关的 unsized 强制规则是
T
到dyn U
,当T
实现U + Sized
并且U
是对象安全的。
那里没有太多空间用于特殊外壳,至少在当前版本的 Rust 中没有。
但是,如果您愿意深入了解 Nightly-only 功能,那么您将获得令人兴奋的CoerceUnsized
trait ,其预期用例是......指向像Box
一样强制的事物的智能指针。
#![feature(unsize, coerce_unsized)]
use std::ops::CoerceUnsized;
use std::marker::Unsize;
impl<T, U> CoerceUnsized<MyBox<U>> for MyBox<T> where T: Unsize<U>, U: ?Sized {}
这告诉 Rust,如果T
与U
“基本相同”,我们可以将MyBox<T>
强制转换为MyBox<U>
,以获得“基本相同”的适当定义。 实现时不需要函数; trait impl
只需要存在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.