[英]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.