当try 从特征内的默认实现返回特征对象时,例如

trait Foo {
    fn foo(self: Box<Self>) -> Box<dyn Foo> {
        self
    }
}

铁 rust 编译器抱怨说

error[E0277]: the size for values of type `Self` cannot be known at compilation time
note: required for the cast to the object type `dyn Foo`

类型强制转换应该是从Box<Self>Box<dyn Foo>,为什么这需要调整自身的大小?

推荐答案

不可能将未调整大小的类型转换为特征对象,因为这将强制它同时具有两组元数据.

请考虑以下代码:

trait Foo: 'static {
    fn foo(self: Box<Self>) -> Box<dyn Foo> {
        self
    }
}

trait Bar {}

impl Foo for dyn Bar {}

impl Foo for i32 {}

impl<T> Bar for T {}

fn main() {
    let boxed = Box::new(42);
    boxed.foo();

    let boxed: Box<dyn Bar> = Box::new(42);
    boxed.foo();
}

在这种情况下,没有任何东西会禁止最后一次调用-所有签名都允许这样做.但是,如果我们将Box<dyn Bar>强制为Box<dyn Foo>,dyn Bar的虚拟函数表将go 哪里?(当然,在本例中它是空的,但它仍然必须存在-空特征并不特殊)

但是,如果您将where Self: Sizedfoo相加,则最后一个呼叫将被正确拒绝:

error: the `foo` method cannot be invoked on a trait object
  --> src/main.rs:20:11
   |
2  |     fn foo(self: Box<Self>) -> Box<dyn Foo> where Self: Sized {
   |                                                         ----- this has a `Sized` requirement
...
20 |     boxed.foo();
   |           ^^^

Rust相关问答推荐

为什么复印是豆荚的一个重要特征?

如何将`Join_all``Vec<;Result<;Vec<;Foo&>;,Anywhere::Error&>;`合并到`Result<;Vec<;Foo&>;,Anywhere::Error&>;`

在使用#[NO_STD]时,如何在Rust中收到紧急消息?

在Rust中是否可以使用Rc自动化约束传播

将PathBuf转换为字符串

在Rust 中移动原始指针的靶子安全吗

在macro_rule中拆分模块和函数名

解析程序无法在Cargo 发布中 Select 依赖版本

习语选项<;T>;到选项<;U>;当T->;U用From定义

Rust ndarray:如何从索引中 Select 数组的行

Rust wasm 中的 Closure::new 和 Closure::wrap 有什么区别

确保参数是编译时定义的字符串文字

borrow 是由于对 `std::sync::Mutex>` 的解引用强制而发生的

如何处理闭包中的生命周期以及作为参数和返回类型的闭包?

当没有实际结果时,如何在 Rust 中强制执行错误处理?

Rust中的一生语法有什么作用?

从嵌入式 Rust 中的某个时刻开始经过的时间

为什么基于 clap::Parser 读取的大量数字进行计算比硬编码该数字时慢?

为什么这个值在上次使用后没有下降?

基于名称是否存在的条件编译