在 Rust 中,引用以及Box<T>、Rc<T>、 和Arc<T>允许创建特征对象(例如, fromBox<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>,
}
Run Code Online (Sandbox Code Playgroud)
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>>`
Run Code Online (Sandbox Code Playgroud)
不幸的是,对于 Rust Stable 来说,答案似乎是“你不需要”。Rust 非常保守,它允许隐式强制转换。特别是,从文档中,我们看到了适用于 的规则Box。
允许在以下类型之间进行强制转换:
...
TyCtor(
T) 到 TyCtor(U),其中 TyCtor(T) 是以下之一
&T&mut T*const T*mut TBox<T>以及可以通过unsized 强制
U从哪里获得。T
其中相关的未定型强制规则是
T到dyn U,当T实现时U + Sized,并且U是对象安全的。
那里没有太多空间用于特殊外壳,至少在当前版本的 Rust 中没有。
然而,如果您愿意深入研究仅限夜间的功能,那么您会得到令人兴奋的CoerceUnsized特征,其预期用例是......指向会像 will 一样强制的事物的智能指针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 {}
Run Code Online (Sandbox Code Playgroud)
这告诉 Rust 我们可以强制MyBox<T>ifMyBox<U>与T是“基本相同” U,以获得“基本相同”的适当定义。实现上不需要任何功能;该特质impl只需要存在即可。
| 归档时间: |
|
| 查看次数: |
307 次 |
| 最近记录: |