簡體   English   中英

創建 Box 時如何轉換為 dyn Trait<dyn trait></dyn>

[英]How to cast to dyn Trait when creating a Box<dyn Trait>

在以下代碼中:

trait Animal {}
struct Dog {}
impl Animal for Dog {}
fn main() {
    // first two lines are OK as expected
    let _animal1: Box<dyn Animal> = Box::new(Dog {});
    let _animal2: Box<dyn Animal> = Box::new(Dog {}) as Box<dyn Animal>;
    // next line is a compile error: cast to unsized type: `Dog` as `dyn Animal`
    let _animal3: Box<dyn Animal> = Box::new(Dog {} as dyn Animal);
}

為什么將Dog{}轉換為dyn Animal會出錯?

對於這個例子,編譯器正確地推斷出類型並且轉換是多余的。 但是對於一般情況,應該使用什么來向編譯器而不是dyn Animal提供類型信息。

以不同的方式向 state 提問:如果 object 不是dyn Animal ,它是什么類型的Box::new()

我的理解是,每個對 object 的引用(例如&T&mut TBox<T>Arc<T>等)都可以在知道 object 的大小(例如滿足Sized特征)的情況下存在。 示例中的前兩行就是這種情況。

但是,在第三行中,您簡要地(在將其傳遞給Box::new()之前)將其轉換為dyn Animal ,這不是引用,而是 object。Rust 中存在的每個 object 都需要具有已知大小,否則 Rust 將不知道在堆棧上為其分配多少空間。 這不是引用的問題,因為引用具有獨立於它們所引用的 object 的恆定大小。

考慮一下:

let dog = Dog{};
// Works
let _animal : &dyn Animal = &dog as &dyn Animal;
// Fails
let _animal : dyn Animal = dog as dyn Animal;

我認為錯誤消息非常具有解釋性:

error[E0620]: cast to unsized type: `Dog` as `dyn Animal`
  --> src/main.rs:13:32
   |
13 |     let _animal : dyn Animal = dog as dyn Animal;
   |                                ^^^^^^^^^^^^^^^^^
   |
help: consider using a box or reference as appropriate
  --> src/main.rs:13:32
   |
13 |     let _animal : dyn Animal = dog as dyn Animal;
   |                                ^^^

For more information about this error, try `rustc --explain E0620`.

你問題的第二部分是“我應該用什么把狗變成動物?”。

我會回答:這取決於你是否想繼承所有權。

如果您不想繼承所有權而是保留原始 object:

let dog = Dog{};
let animal: &dyn Animal = &dog;

否則,如果您想將所有權轉移到動物 object 中:

let dog = Dog{};
let animal: Box<dyn Animal> = Box::new(dog);

正如編譯器所說,您不能轉換為dyn類型,因為它未調整大小。 也就是說,堆棧中不能存在dyn T類型的值。

您只能在類似指針的構造后面使用dyn類型,例如&dyn _Box<dyn _> ,因為額外的間接級別意味着dyn object 本身不存在,它只是類型系統的構造。

那些自動處理內部轉換。 正如您所注意到的,您不需要顯式強制轉換,強制轉換是隱式的。

這些類似於指針的類型通過神奇的CoerceUnsized特性(仍然不穩定)進行轉換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM