有没有办法将Box<Box<Foo + Send>>转换为Box<Box<Foo>>?

  • 本文关键字:Box Foo 转换 Send 有没有 rust
  • 更新时间 :
  • 英文 :


考虑这样的代码:

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是一种从Box<Trait>为 C 库提供void *指针的方法。由于胖指针,我无法将Box<Foo>转换为void *

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

这里有一种方法:取消引用b(将其"取消装箱"到Box<Foo + Send>),然后立即将其包装在另一个Box<T>中,允许编译器推断出正确的T(在本例中为Box<Foo>)。

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

这是有效的,因为Box<Foo + Send>可以自动强制Box<Foo>,但Box<Box<Foo + Send>>不能被强制Box<Box<Foo>>

虽然你已经声明你不能改变consume_func,但其他有类似问题的人可以改变它以接受泛型:

fn consume_func<F: Foo + ?Sized>(b: Box<Box<F>>) {
unimplemented!();
}

最新更新