gpt4 book ai didi

rust - 为什么在特征中返回 `Self` 有效,但返回 `Option` 需要 `Sized` ?

转载 作者:行者123 更新时间:2023-11-29 07:42:26 25 4
gpt4 key购买 nike

这个特征定义编译得很好:

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超特质绑定(bind),它有效。

我知道 Self输入特征不会自动绑定(bind)为 Sized .我明白 Option<Self>不能返回(通过堆栈),除非它被调整大小(反过来,需要 Self 被调整大小)。但是,Self 也是如此。作为返回类型,对吧?它也不能存储在堆栈上,除非它的大小。

为什么第一个特征定义没有触发该错误?

( This question 是相关的,但它没有回答我的确切问题——除非我不明白。)

最佳答案

这里进行了两组检查,这就是差异看起来令人困惑的原因。

  1. 函数签名中的每个类型都经过有效性检查。 Option 本质上需要 T: Sized。不需要 Sized 的返回类型就可以了:

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

    existing answer涵盖了这一点。

  2. 任何有函数体的函数还会检查所有参数是否都Sized。没有主体的特征函数不会应用此检查。

    为什么这有用?允许在特征方法中使用未确定大小的类型是允许按值特征对象 的关键部分,这是一个非常有用的特性。例如,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 - 为什么在特征中返回 `Self` 有效,但返回 `Option<Self>` 需要 `Sized` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54465400/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com