代码之家  ›  专栏  ›  技术社区  ›  Xiao_e_yun

将泛型中的Box<T>转换为rust中的Box>dyn Trait>

  •  1
  • Xiao_e_yun  · 技术社区  · 3 年前

    如何将泛型中的Box转换为Box。
    从…起 Container<Box<Dog>> Container<Box<dyn Animal>>

    //example
    fn main() {
      let container: Container<Box<Dog>> = Container(Box::new(Dog()));
    
      let test: Container<Box<dyn Animal>> = container;
      // expected struct `RcHash<Box<dyn Enity>>`
      // found struct `RcHash<Box<Role>>`
    
      let test = container as Container<Box<dyn Animal>>;
      // non-primitive cast: `Container<Box<Dog>>` as `Container<Box<dyn Animal>>`
      // an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
    }
    
    //struct
    struct Container<T> (T);
    struct Dog ();
    
    //trait
    trait Animal { fn echo(&self); }
    impl Animal for Dog { fn echo(&self) { println!("dog"); } }
    
    1 回复  |  直到 3 年前
        1
  •  0
  •   at54321    3 年前

    你不能做简单的事 铸造 之间 Box<Dog> Box<dyn Animal> ,因为它们不是完全一样的东西。二者都 Box es可能充当指向 Dog 例如,但是 方框<dyn动物> 实际上会有不同的 大小 ,因为trait对象还有一个额外的指针(用于 vtable )。我建议你阅读 this 以更好地理解关于特质对象的部分。

    以上意味着你无法避免创建一个新的 方框<dyn动物> 例如,因此您无法避免创建 Container<Box<dyn Animal>> 实例(因为如果 A != B => Container<A> != Container<B> /在这里你可以解读 != 为“不兼容”或“不同 大小 ’/)。

    下面是一个如何“手动”创建新 方框<dyn动物> 的实例 方框<狗> 实例:

    let dog_box: Box<Dog> = Box::new(Dog());
    let animal: Box<dyn Animal> = Box::new(*dog_box);
    

    这将从根本上 移动 doggie实例(不创建另一个克隆)。

    这是您案例中更完整的示例:

    let container: Container<Box<Dog>> = Container(Box::new(Dog()));
    let cont_animal: Container<Box<dyn Animal>> = Container(Box::new(*container.0));
    
    推荐文章