将 Arc 克隆为 Arc,其中 T 实现 U

2023-11-22

我觉得很奇怪

use std::sync::Arc;

trait Fruit {}
struct Pear {}
impl Fruit for Pear {}

fn main() {
    let pear = Arc::new(Pear {});
    let cloned = Arc::clone(&pear);
    let cloned_casted: Arc<dyn Fruit> = cloned;
}

编译,但是

use std::sync::Arc;

trait Fruit {}
struct Pear {}
impl Fruit for Pear {}

fn main() {
    let pear = Arc::new(Pear {});
    let cloned_casted: Arc<dyn Fruit> = Arc::clone(&pear);
}

错误与

error[E0308]: mismatched types
 --> main.rs:9:52
  |
9 |     let cloned_casted: Arc<dyn Fruit> = Arc::clone(&pear);
  |                                                    ^^^^^ expected trait object `dyn Fruit`, found struct `Pear`
  |
  = note: expected reference `&Arc<dyn Fruit>`
             found reference `&Arc<Pear>`

为什么会这样,是否有更短的变体可供克隆Arc<dyn Fruit> from Arc<Pear>?


这是 Rust 中类型推断的工作原理的结果。方法Arc::clone()接受一个&Arc<T>。编译器需要确定什么T is.

在第一个代码片段中,编译器对返回类型没有任何限制Arc::clone(&pear),因此推断T基于传入的参数。该参数具有类型&Arc<Pear>,所以编译器推断T = Pear。代码片段中的最后一行隐式执行未大小的强制转换Arc<Pear> to Arc<dyn Fruit>.

在第二个代码片段中,编译器已经知道所需的返回类型Arc::clone(&pear),因为目标变量包含类型注释。据此,编译器推断T = dyn Fruit并期望一个类型的参数&Arc<dyn Fruit>。然而,它发现一个&Arc<Pear>相反,它不能被强制转换为所需的类型,因此编译器会出错。

目前尚未完全指定类型推断在 Rust 中如何工作的详细信息。每当编译器没有推断出正确的类型时,您应该添加显式类型提示:

let pear = Arc::new(Pear {});
let cloned_casted: Arc<dyn Fruit> = Arc::<Pear>::clone(&pear);

这样,编译器就不需要推断什么T是,并且代码按预期工作。

有时您还可以推动编译器推断正确的类型。这也有效:

let cloned_casted: Arc<dyn Fruit> = Arc::clone(&pear) as _;

编译器可以推断_意思是Arc<dyn Fruit>,但它不再知道你正在投射什么类型from,因此它需要以与第一个代码片段中相同的方式推断该类型。

也可以看看:

  • rustc 开发指南中关于类型推断的章节
  • Hindley-Milner 类型推理
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 Arc 克隆为 Arc,其中 T 实现 U 的相关文章

随机推荐

  • 从控制台将 MongoDB 字段的类型更改为整数

    我们有一个应用程序 它在 MongoDB 中存储来自 C C 的一些配置值 并且能够重新启动 即 它运行一段时间 有人中断该应用程序 更改配置 然后再次运行该应用程序 然后它会在哪里恢复 它停止了 这就像布尔值和字符串配置的魅力一样 但是我
  • Microsoft Access 中的 Scope_Identity()

    我正在 Microsoft Access 中编写一个数据库 以使客户不必购买 SQL Server 如何获取我刚刚插入的行的主键 在 SQL Server 中 它是 INSERT INTO TABLE FIELDLIST VALUES VA
  • Javascript 复选框 onChange

    我的表单中有一个复选框 我希望它根据以下场景工作 如果有人检查它 文本字段的值 totalCost 应设置为10 然后 如果我返回并取消选中它 一个函数calculate 设置值totalCost根据表格中的其他参数 所以基本上 我需要这样
  • MultiPartParserError:- 无效边界

    我尝试使用 Python requests 模块将一些数据和文件发送到我的 django Rest 应用程序 但出现以下错误 raise MultiPartParserError Invalid boundary in multipart
  • PHP 代码生成安全 URL?

    我们需要从书名生成一个唯一的 URL 其中书名可以包含任何字符 我们如何搜索替换所有 无效 字符 以便生成有效且简洁的 URL 例如 The Great Book of PHP www mysite com book 12345 the g
  • 将 Pandas DataFrame 写入 Excel:如何自动调整列宽

    我正在尝试将一系列 pandas DataFrame 写入 Excel 工作表 以便 工作表的现有内容不会被覆盖或删除 并且 Excel 列宽度会调整以适应列条目的长度 这样我就不必在 Excel 中手动执行此操作 对于 1 我找到了一个很
  • 保存和恢复 ExpandableListActivity 的展开/折叠状态

    我有一个 ExpandableListActivity 使用 SimpleCursorTreeAdapter 当用户单击子元素时 它会启动另一个活动 当在新活动中按下后退按钮时 所有列表项都会再次折叠 如何保存 ExpandableList
  • 注意:使用未定义的常量 DB_HOST - 在第 31 行的 C:\xampp\htdocs\blog\system\functions.php 中假定为“DB_HOST”

    犯了几个错误 我一辈子都看不到自己在哪里失败了 下面是函数文件
  • 初始化 constexpr 静态类成员时出现编译器错误

    我用以下方式声明了一个类 class A struct B constexpr B uint8 t a uint8 t b a a b b bool operator const B rhs const if a rhs a b rhs b
  • 将列表中的连续数字组合在一起

    我有一个有序的 Python 表单列表 1 2 3 4 5 12 13 14 15 20 21 22 23 30 35 36 37 38 39 40 如何将列表中的连续数字分组在一起 像这样的一个团体 1 2 3 4 5 12 13 14
  • 在 Heroku 上安装私有 ssh 部署密钥

    我正在创建一个 Node js 应用程序 用作 Github 的 Web 挂钩 当推送更改时 它将自动部署某个私有存储库 为了使 webhook 应用程序尽可能高效 我想在部署时将私有存储库克隆并拉入 webhook 的 Heroku 实例
  • 在 matplotlib 颜色条中对齐刻度标签

    我有一个带有正值和负值的颜色条 这些值是自动生成的 我没有设置它们 不幸的是 减号破坏了文本的垂直对齐方式 如何将刻度标签中的所有文本向右对齐 或者在正数之前插入一个空格以使其看起来不错 您可以更改文本的对齐方式 可能需要稍微更改标签的 x
  • 为什么 Traversable 不能多次访问其元素?

    我记得在某处读过 像这样的类型不可能Traversable data Bar a Bar a deriving Show instance Functor Bar where fmap f Bar x Bar f x instance Fo
  • 如何获取数组项的类型?

    如果我有一个类型type foo Array lt name string test number gt 是否可以获取数组中值的类型 在本例中为接口 我知道有keyof要获取密钥 是否有类似的值 如果您正在寻找如何提取 name strin
  • 地图视图平滑缩放

    当我使用 MapController setZoom x 时 例如 从级别 5 缩放到 15 时 缩放执行得非常快 并且通常不会加载新级别的地图图块 这对用户来说看起来不太好 任何地图内置功能都可以将其更改为更慢的缩放 以便在达到 15 级
  • Android:编辑文本中密码的最小长度

    在android中 有没有简单的方法可以在edittext中设置最小密码长度 在 xml 中只有最大长度选项 而没有最小长度选项 设置 em 和宽度等选项来限制长度 但是什么时候设置最小长度呢 我在文档中找到了这个 DevicePolicy
  • 浮点型与双精度型

    是否存在比较 equals 两个浮点值之间将返回false如果你将它们比较DOUBLE但返回true如果你将它们与 FLOAT 进行比较 作为我的小组项目的一部分 我正在编写一些程序来比较任何给定类型的两个数值 我总共需要处理四种类型 do
  • Java 中的 double 到 long 无需转换

    我需要将 double 转换为 long 保留其二进制结构 而不是数值 只需更改类型 但保留二进制值不变 有没有一种本地方法可以做到这一点 有Double与 doubleToLongBits 和 doubleToLongRawBits Ja
  • 如何在 Hibernate 中使用唯一键而不是主键检索记录

    Using session load or session get 或任何其他方法org hibernate session 是否可以在hibernate中根据Unique列而不是PK列值获取记录 我的要求是我需要根据唯一列值而不是主键获取
  • 将 Arc 克隆为 Arc,其中 T 实现 U

    我觉得很奇怪 use std sync Arc trait Fruit struct Pear impl Fruit for Pear fn main let pear Arc new Pear let cloned Arc clone p