这个trait 定义可以很好地编译:

trait Works {
    fn foo() -> Self;
}

然而,这会导致以下错误:

trait Errors {
    fn foo() -> Option<Self>;
}
error[E0277]: the size for values of type `Self` cannot be known at compilation time
 --> src/lib.rs:6:5
  |
6 |     fn foo() -> Option<Self>;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `Self`
  = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
  = help: consider adding a `where Self: std::marker::Sized` bound
  = note: required by `std::option::Option`

有了: Sized个supertrait绑定,它就可以工作了.

我知道,Self种类型的trait 并不是自动地就一定是Sized种.我知道Option<Self>不能被返回(通过堆栈),除非它被调整大小(反过来,需要调整Self的大小).然而,Self作为返回类型也是一样的,对吗?它也不能存储在堆栈上,除非大小合适.

Why doesn't the first trait definition already trigger that error?

(100 is related, but it doesn't answer my exact question – unless I didn't understand it.)

推荐答案

这里有两组判断,这就是为什么差异看起来令人困惑.

  1. 判断函数签名中的每个类型的有效性.Option岁就需要T: Sized岁.不需要Sized的返回类型可以:

    trait Works {
        fn foo() -> Box<Self>;
    }
    

    existing answer号覆盖了这口井.

  2. 任何函数with a body还判断所有参数是否为Sized.没有身体的trait 功能不适用此判断.

    这为什么有用?允许在trait方法中使用非大小的类型是允许by-value trait objects的一个关键部分,这是一个非常有用的特性.例如,FnOnce不要求SelfSized:

    pub trait FnOnce<Args> {
        type Output;
        extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
    }
    
    fn call_it(f: Box<dyn FnOnce() -> i32>) -> i32 {
        f()
    }
    
    fn main() {
        println!("{}", call_it(Box::new(|| 42)));
    }
    

非常感谢pnkfelix and nikomatsakis for answering my questions on this topic.

Rust相关问答推荐

如何处理对打包字段的引用是未对齐错误?

WebDriver等待三十四?(Rust Se)

Rust kill std::processs::child

使用pyo3::Types::PyIterator的无限内存使用量

这种获取-释放关系是如何运作的?

像这样的铁 rust 图案除了‘选项’之外,还有其他 Select 吗?

是否可以使用Rust宏来构建元组的项?

如何实现Deref;多次;?

如何使用reqwest进行异步请求?

考虑到Rust不允许多个可变引用,类似PyTorch的自动区分如何在Rust中工作?

Rust从关联函数启动线程

什么是`&;[][..]`铁 rust 里的刻薄?

go 重并堆积MPSC通道消息

在1.5n次比较中找到整数向量中的最大和次大整数

Rust 打包在 .deb 中

没有明确地说return会产生错误:match arms have incompatible types

(let b = MyBox(5 as *const u8); &b; ) 和 (let b = &MyBox(5 as *const u8); ) 之间有什么区别

如何将 Rust 中的树状 struct 展平为 Vec<&mut ...>?

如何在 use_effect_with_deps 中设置监听器内的状态?

在 Rust 中如何将值推送到枚举 struct 内的 vec?