不能 return Option<associated type> 因为关联类型没有调整大小

Cannot return Option<associated type> because associated type is not sized

我不明白为什么这段代码不能编译:

fn main() {}

trait NotWorking {
    // The associated type `Bar` must be sized
    type Bar: ?Sized;

    // Why does the compiler complain that Self::Bar is not sized?
    // I have a trait bound that says it is!
    fn notwoking() -> Option<Self::Bar>;
}

我确实有一个约束,即关联类型 Bar 必须调整大小,但编译器仍然抱怨它未调整大小:

error[E0277]: the trait bound `<Self as NotWorking>::Bar: std::marker::Sized` is not satisfied
  --> src/main.rs:17:5
   |
17 |     fn notwoking() -> Option<Self::Bar>;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<Self as NotWorking>::Bar` does not have a constant size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `<Self as NotWorking>::Bar`
   = help: consider adding a `where <Self as NotWorking>::Bar: std::marker::Sized` bound
   = note: required by `std::option::Option`

我试了一下,试图让它工作,并且很惊讶它能工作(因为我们不能 return 一个没有大小的类型,我原以为它会失败):

fn main() {}

trait Working {
    type Bar;

    // Why does this work?
    // I would expect the compiler to complain the Self::Bar is not sized
    fn woking() -> Self::Bar;
}

我肯定遗漏了一些重要的东西。

答案在最后一串:

required by `std::option::Option`

我不是专家,但我想编译器需要有关类型大小的信息,以了解如何在内存中布局枚举 OptionBar 类型的变体。

你的第二个例子是正确的。使用 Sized 边界声明通用参数的方式是不指定任何显式边界。 Sized 的特殊之处在于默认情况下它被隐式添加为泛型参数的绑定,因为不是 Sized 的情况相对不常见。如果您不想要求通用参数在编译时具有已知大小,您可以 .

另见 documentation for Sized