为什么在特征中返回“Self”可以工作,但返回“Option”需要“Sized”?

2024-05-11

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

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

我知道Self输入特征不会自动绑定为Sized。我明白Option<Self>不能返回(通过堆栈),除非它的大小(反过来,需要Self来确定尺寸)。然而,同样的情况也适用于Self作为返回类型,对吧?除非调整了大小,否则它也不能存储在堆栈中。

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

(这个问题 https://stackoverflow.com/questions/30938499/why-is-the-sized-bound-necessary-in-this-trait是相关的,但它并没有回答我的确切问题——除非我不明白。)


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

  1. 检查函数签名中的每种类型的有效性。Option本质上需要T: Sized。不需要的返回类型Sized很好:

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

    The 现有答案 https://stackoverflow.com/a/54465962/155423很好地涵盖了这一点。

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

    为什么这有用?允许在特征方法中使用未确定大小的类型是允许按值特征对象,一个非常有用的功能。例如,FnOnce不需要Self be Sized:

    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 和 nikomatsakis 回答了我关于这个主题的问题 https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/questions.20from.20Stack.20Overflow/near/157298199.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在特征中返回“Self”可以工作,但返回“Option”需要“Sized”? 的相关文章

随机推荐

  • #elif 定义时不带括号

    使用 VS2005 和 BLAH BLAH 定义以下预处理器条件为 false elif defined BLAH BLAH 但如果我把它改成 elif defined BLAH BLAH 是真的 为什么括号在这里会有所不同 它应该没有任何
  • 我如何在 Visual Studio 2012 中同时构建项目(dll 和 lib)

    我设法在 dll 模式和库模式下设置构建项目 但不能同时设置 对于构建在 dll 中 项目 gt 属性 gt 配置类型 动态库 dll 项目 gt 属性 gt 目标扩展名 dll 对于内置库 项目 gt 属性 gt 配置类型 静态库 lib
  • Sigar API for JAVA(需要指南)

    我已经下载了 Sigar API http support hyperic com display SIGAR Home http support hyperic com display SIGAR Home 并希望在项目中使用它来获取有关
  • Java 阻止列表实现

    我在 SO 和 Google 上搜索了这个问题的答案 但到目前为止找不到合适的解决方案 我目前正在研究图形路由问题中的 LayerManager 管理器负责提供和重置一组固定的层 我想使用阻止列表来实现消费者 生产者模式 以便只要没有可用的
  • 什么是 C# 类 StreamContent?

    这可能在网络上的某个地方有解释 但我找不到它 StreamContent 到底是什么 我试图理解 C 但我无法正确理解一些 WebAPi 示例 因为我不明白 StreamContent 是什么 一个完整解释它的链接 而不是像 MSDN 那样
  • C# NetworkStream.Read 奇怪之处

    谁能指出这段代码中的缺陷吗 我正在使用 TcpClient 检索一些 HTML 与 IIS 服务器通信时 NetworkStream Read 似乎永远不会完成 如果我改用 Fiddler 代理 它可以正常工作 但是当直接与目标服务器对话时
  • 如何诊断这些 PHP 代码覆盖分段和 zend_mm_heap 损坏错误

    我一直很高兴在我的 Ubuntu 机器上编码 这是一台拥有大量内存的强大机器 我正在研究 4 个新课程 一边编写和运行单元测试 在某些时候 我注意到 虽然单元测试完成得很好 但代码覆盖率却没有 在消息 正在生成代码覆盖率报告 等 之后 我会
  • 内部注册 vs. OpenID vs. Google Friend Connect vs. Facebook Connect vs.(等等)

    我正在尝试决定如何允许用户注册我的网站 有 openID clickpass facebook connect googlefriendconnect 等 或者是老式的内部 输入用户名 电子邮件 密码等 简要地看一下如何设置 OpenID
  • Objective C - 动态属性的respondsToSelector

    我目前面临的问题是检查对象 NSManagedObject 的属性是否存在 不幸的是方法 MyObject class respondsToSelector selector myProperty 总是返回NO 我认为这是因为CoreDat
  • TX 未发送至公证服务的情况有哪些?

    交易未提交公证服务的情况有哪些 尽管进度跟踪器显示公证步骤 但我们注意到在某些情况下交易并未真正发送到公证服务 例如 没有时间窗口的状态创建 从 Corda 3 3 开始 如果 Tx 没有输入且没有时间窗口 则不会将其发送给公证人进行签名
  • 添加 Javascript 按钮来更改 iframe 的内容

    我正在尝试创建此页面 其中有一个 Iframe 并且我想添加一个按钮来显示 iframe 中的下一页 以及一个按钮来显示 iframe 中的上一页 我总共有 4 个页面要在名为 1 html 2 html 3 html 4 html 的 i
  • 我应该使用哪个 Linux 发行版作为 Xen 主机? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我为家庭办公室订购了一台服务器 我想用 Xen 对其进行分区 我认为这将使事情保持干净并且更容易维护 我将运行 MySQL PostgreSQL
  • 为什么 MATLAB 本机函数 cov(协方差矩阵计算)使用与我预期不同的除数?

    给定一个 M 维和 N 个样本的数据矩阵数据 例如 data randn N M 我可以计算协方差矩阵 data mu data ones N 1 mean data cov matrix data mu data mu N 如果我使用原生
  • 查找PID所属的tmux会话

    我正在使用 htop 所以看看哪些进程占用了大量内存 以便我可以杀死它们 我有很多 tmux 会话和很多类似的流程 如何检查 PID 位于哪个 tmux 窗格中 以便确定我正在杀死我想杀死的东西 鉴于PID下面一行是目标 pid 号 tmu
  • SQL Server - 删除语句增加日志大小

    我有一个LOGGIN数据库很大 400 GB 它有数百万行 我刚刚跑了一个delete该语句花费了 2 5 小时并删除了可能数百万行 delete FROM DB dbo table where Level not in info erro
  • R中一张图中的多个条形图

    我是 R 初学者 我需要创建一个像这样的图表 https i stack imgur com az56z jpg https i stack imgur com az56z jpg 我不知道如何生成整个数据集 基本思想是某个外显子 ID 会
  • 传递 oauth 令牌请求的授权标头

    我使用java实现oauth来获取未经授权的请求令牌 如何传递授权标头中的参数 我需要通过 GET request token HTTP 1 1 Host photos example net 80 Authorization OAuth
  • 如何在 GTX 560 及更高版本上使用 OpenGL 进行立体 3D?

    我正在使用在 Windows 7 上运行的开源触觉和 3D 图形库 Chai3D 我重写了该库以使用 Nvidia nvision 执行立体 3D 我将 OpenGL 与 GLUT 一起使用 并使用 glutInitDisplayMode
  • 将数组从控制器传递到视图

    I have UIView UI视图控制器 在 UIViewController 中 我需要能够将项目插入到 6 个整数的固定数组中 然后 我需要将此数组传递给视图 以便它分析该数组并适当地更新屏幕 我该怎么做呢 我尝试过使用标准 C 数组
  • 为什么在特征中返回“Self”可以工作,但返回“Option”需要“Sized”?

    这个特征定义编译得很好 trait Works fn foo gt Self 然而 这确实会导致错误 trait Errors fn foo gt Option