为什么除非使用临时变量,否则我不能推入 dyn Trait 的 Vec ?

2023-12-01

这是我的代码:

use std::rc::{Rc, Weak};
use std::cell::RefCell;

trait Trait {}

fn push<E: Trait>(e: E) {
    let mut v: Vec<Rc<RefCell<Box<dyn Trait>>>> = Vec::new();
    
    // let x = Rc::new(RefCell::new(Box::new(e)));
    // v.push(x); // error

    v.push(Rc::new(RefCell::new(Box::new(e)))); // works fine
}

The v.push(x)引发此错误:

error[E0308]: mismatched types
  --> src/main.rs:12:12
   |
7  | fn push<E: Trait>(e: E) {
   |         - this type parameter
...
12 |     v.push(x);
   |            ^ expected trait object `dyn Trait`, found type parameter `E`
   |
   = note: expected struct `std::rc::Rc<std::cell::RefCell<std::boxed::Box<dyn Trait>>>`
              found struct `std::rc::Rc<std::cell::RefCell<std::boxed::Box<E>>>`

但是,如果我将值(用完全相同的值和类型构造)直接推入向量中,它编译时不会出现错误。

那么为什么第一个版本不能编译呢?我应该改变什么才能使它可以使用x在将其推入向量之前?


这一切都在类型推断中。当你写:

v.push(Rc::new(RefCell::new(Box::new(e))));

Rust 可以从上下文中看出,RefCell::new()必须是一个Box<dyn Trait>,所以尽管提供了Box<E>,它将其强制为前一种类型。另一方面,当你这样写时:

let x = Rc::new(RefCell::new(Box::new(e)));
v.push(x); // compile error

Rust 首先推断x类型的Rc<RefCell<Box<E>>>你不能再push它变成一个vec of Rc<RefCell<Box<dyn Trait>>>。您可以通过在您的代码中添加显式类型注释来更改此设置let绑定预先告诉 Rust 你确实想要一个Rc<RefCell<Box<dyn Trait>>>:

use std::rc::{Rc, Weak};
use std::cell::RefCell;

trait Trait {}

fn push<E: Trait>(e: E) {
    let mut v: Vec<Rc<RefCell<Box<dyn Trait>>>> = Vec::new();

    let x: Rc<RefCell<Box<dyn Trait>>> = Rc::new(RefCell::new(Box::new(e)));
    v.push(x); // compiles
}

操场

这里要理解的重要一点是E 不一样 as dyn Trait. E是一些已知的具体实现Trait while dyn Trait是一个特征对象,其底层具体实现已被删除。

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

为什么除非使用临时变量,否则我不能推入 dyn Trait 的 Vec ? 的相关文章

随机推荐

  • 防止双重表单提交

    我正在尝试调整一些现有的网络应用程序 以防止用户意外地点击提交按钮并提交表单两次 我认为 jquery 将是执行此操作的最佳方法 尽管我的页面在其他方面使用很少的 jquery 我在这里发现了很多类似的问题 答案非常有用 但仍然没有提供完整
  • 如何在 PHP 中解码 AMF3 编码的 AS3 对象

    我正在尝试在 PHP 中解码通过套接字从 Flash 发送的对象 我尝试使用 AMFPHP 和 ZEND AMF 但都不起作用 有人可以指出我在 php 中解码 AMF3 编码对象而不使用 AMFPHP 的远程功能的方法吗 数据是通过套接字
  • 当您使用 Docker 提交容器时到底发生了什么?

    我知道当你使用 例如 docker commit abcdefgh ola minhaimagem 1 0您正在保存您的更改abcdefgh将容器放入新映像中以便将来再次使用 然而 我注意到有时提交运行得非常慢 这一事实在我脑海中产生了一个
  • 当我安装了 Java 7 时,cassandra 2 抱怨 Java 7

    cassandra Cassandra 2 0 and later require Java 7 or later 好的 初始化脚本的那部分发生了什么 java ver output JAVA java version 2 gt 1 jvm
  • Java中如何以不区分大小写的方式检查一个字符串是否包含另一个字符串?

    假设我有两根弦 String s1 AbBaCca String s2 bac 我想执行一项检查返回该信息s2包含在s1 我可以这样做 return s1 contains s2 我很确定contains 区分大小写 但是我无法通过阅读文档
  • 如何在 JavaScript 中进行字符串插值?

    考虑这段代码 var age 3 console log I m age years old 除了字符串连接之外 还有其他方法可以将变量的值插入到字符串中吗 从 ES6 开始 你可以使用模板文字 const age 3 console lo
  • www 数据权限?

    所以我在 var www 中有一个目录 称为 cake 我需要允许 www data 写入它 但我也想写入它 无需使用 sudo 我担心将权限更改为 777 以防我的计算机上的其他用户 或黑客 尝试修改该目录中的文件 如何只允许我自己和 A
  • 从 MySQL 表中删除唯一约束

    如何使用 phpMyAdmin 将 唯一键约束 删除到 MySQL 表的列上 唯一约束也是索引 首次使用SHOW INDEX FROM tbl name找出索引的名称 索引的名称存储在名为的列中key name在该查询的结果中 然后你可以使
  • Oracle 查询 - 使用逗号分隔数据连接

    表名称 crm mrdetails id mr name me email mr mobile mr doctor 1 John email protected 1234555555 1 2 3 表名称 crm mr doctor id d
  • 我应该使用 pt 还是 px?

    有什么区别pt and px在CSS中 我应该使用哪一个 为什么 px 像素 所有这些答案似乎都是不正确的 与直觉相反 在 CSS 中px 不是像素 至少 不是简单的物理意义上的 阅读这篇文章来自W3C EM PX PT CM IN 如何p
  • Python:如何替换旧的上传到 Google Drive 的文件

    我用 python 编写了这个脚本 它查看文件夹 CSVtoGD 列出其中的每个 CSV 并将这些 CSV 作为独立的工作表发送到我的谷歌驱动器 我正在尝试编写一行 当我再次运行程序时 它将删除旧文件 我在这里缺少什么 我正在尝试通过使用以
  • 将war文件转换为可执行文件

    我的公司开发了一个Web应用程序 J2EE环境 Tomcat服务器 并希望将其作为产品出售 客户可以使用该产品作为基本版或高级版 在高级版中 客户有一些额外的功能 可能是一些额外的链接 这种区别是根据序列号进行的 当讨论上述事情时 我只是一
  • 闪亮:模块UI的updateSelectInput(在insertUI之后)

    以下闪亮的应用程序使用模块 它可以工作 library shiny LHSchoices lt c X1 X2 X3 X4 LHSchoices2 lt c S1 S2 S3 S4 MODULE UI variablesUI lt func
  • Android 上使用 GoogleAccountCredential.newChooseAccountIntent() 时出现 java.lang.NoClassDefFoundError

    我正在使用 Eclipse Juno ADT 捆绑包 Google Plugin for Eclipse 为 Android 4 进行开发 我需要以编程方式登录 Google 帐户才能使用 Google Calendar API 为了 我正
  • 按时间间隔更新 firebase 条目

    我希望能够以分钟为间隔更新 firebase 条目中的某些值 我不确定如何执行此操作 但已尝试以下操作 var interval setInterval function database ref on value function sna
  • 使用 API 21 更改片段时出现图形错误

    我的 Nexus 5 出现图形问题 当我更改片段时 在新片段出现之前 有一个大正方形 其中包含新片段的一部分 过渡并不顺利 我使用 getSupportFragmentManager 作为片段 使用模拟器 API 21 和其他设备 API
  • 使用 jQuery 将 tr 附加到 thead 结果空白表行

    我正在尝试创建thead with tr 来自 JSON 对象数组 这是必需的 因为 jQuery 数据表需要它 我有以下脚本来做到这一点 但创建tr与空白值 function var json Number 10031 Descripti
  • Mercurial (hg) 更新错误,中止:没有这样的文件或目录

    我无法在我的机器上更新 Mercurial 存储库 当我进行更新时出现以下错误hg up traceback Traceback most recent call last File usr lib python2 7 dist packa
  • 在 CodeIgniter 中重定向 index.php

    我创建了一个 CodeIgniter 应用程序 现在我尝试将带有 index php 的 url 重定向到不带它的 url 我当前的 htaccess 是 RewriteEngine On RewriteBase Removes trail
  • 为什么除非使用临时变量,否则我不能推入 dyn Trait 的 Vec ?

    这是我的代码 use std rc Rc Weak use std cell RefCell trait Trait fn push