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

有没有办法把box<box<foo+send>>转换成box<box<foo>>?

  •  2
  • user1244932  · 技术社区  · 7 年前

    考虑这样的代码:

    trait Foo {
        fn foo(&self);
    }
    
    fn consume_func(b: Box<Box<Foo>>) {
        unimplemented!();
    }
    
    fn produce_func() -> Box<Box<Foo + Send>> {
        unimplemented!();
    }
    
    fn main() {
        let b = produce_func();
        consume_func(b);
    }
    

    它不会编译:

    error[E0308]: mismatched types
      --> src/main.rs:24:18
       |
    24 |     consume_func(b);
       |                  ^ expected trait `Foo`, found trait `Foo + std::marker::Send`
       |
       = note: expected type `std::boxed::Box<std::boxed::Box<Foo + 'static>>`
                  found type `std::boxed::Box<std::boxed::Box<Foo + std::marker::Send>>`
    

    双人间 Box a way to give a C library a void * pointer from Box<Trait> 是的。因为胖指针,我不能转换 Box<Foo> 空洞* 是的。

    我不能改变 consume_func ,我宁愿不使用 unsafe 或额外分配。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Shepmaster Tim Diekmann    7 年前

    尽管你说过你不能改变 consume_func ,其他具有类似问题的用户可以将其更改为接受泛型:

    fn consume_func<F: Foo + ?Sized>(b: Box<Box<F>>) {
        unimplemented!();
    }
    
        2
  •  4
  •   Shepmaster Tim Diekmann    7 年前

    有一种方法:取消引用 b (联合拳击) Box<Foo + Send> ),然后立即用另一个 Box<T> ,允许编译器推断正确的 T (在这种情况下 Box<Foo> )中。

    consume_func(Box::new(*b));
    

    这有效是因为 方框<Foo+Send> 可以自动强制 方框<Foo> ,但是 Box<Box<Foo + Send>> 不能强迫 Box<Box<Foo>> .

    推荐文章