rust - 将 Arc<Mutex<Option<Box<MyStruct>>>>> 强制转换为 Arc<Mutex<Option<Box<dyn Trait>>>>> 将不起作用

标签 rust

我正在尝试在 Arc<Mutex<Option<Box<>>>>> 中存储 dyn 特征,但是由于某种原因它不起作用

use std::sync::{Arc, Mutex};

trait A{}

struct B{}

impl A for B{}

struct H{
    c: Arc<Mutex<Option<Box<dyn A>>>>
}

fn main() {
    let c = 
    Arc::new(Mutex::new(Some(Box::new(B{}))));
    H{
        c: c
    };
}

错误:

error[E0308]: mismatched types
  --> src/main.rs:17:12
   |
17 |         c: c
   |            ^ expected trait object `dyn A`, found struct `B`
   |
   = note: expected struct `Arc<Mutex<Option<Box<(dyn A + 'static)>>>>`
              found struct `Arc<Mutex<Option<Box<B>>>>`

Playground

看起来它无法存储 dyn作为Box<B> ,这很奇怪,因为这有效:

fn main() {
    let c: Arc<Mutex<Option<Box<dyn A>>>> = 
    Arc::new(Mutex::new(Some(Box::new(B{}))));
}

有什么区别?

最佳答案

What's the difference?

Box 有一个非常特殊的情况以及其他可以包含动态大小值的标准库类型,例如 dyn A .

let c = Arc::new(Mutex::new(Some(Box::new(B{}))));
H { c: c };

在此代码中,您已初始化变量 c — 没有类型声明 — 其类型被推断为 Arc<Mutex<Option<Box<B>>> 的值,然后尝试将其存储在 Arc<Mutex<Option<Box<dyn A>>> 类型的字段中。这是行不通的,因为这两种类型具有不同的内存布局。

let c: Arc<Mutex<Option<Box<dyn A>>>> = 
    Arc::new(Mutex::new(Some(Box::new(B{}))));

在此代码中,您给出 c类型声明,因此需要 dyn 在其构造时就已知,这使得强制可以很快发生,您可以强制 Box<B>Box<dyn A> ,因为Box实现特殊特征 CoerceUnsized 。 (相同的机制适用于将 &B 转换为 &dyn A 。)但是,这不适用于包含 Box<B> 的任意类型 — 甚至没有Option<Box<B>> ,更不用说更复杂的类型了。

您可以给c构造它时的类型:

let c: Arc<Mutex<Option<Box<dyn A>>>> = Arc::new(Mutex::new(Some(Box::new(B{}))));
H { c: c };

或者,稍短但更奇怪的是,您可以仅注释 Box 的直接容器。与它需要的类型:

let c = Arc::new(Mutex::new(Some::<Box<dyn A>>(Box::new(B{}))));
H { c: c };

或者您可以使用 as 编写显式强制转换运算符:

let c = Arc::new(Mutex::new(Some(Box::new(B{}) as Box<dyn A>)));
H { c: c };

关于rust - 将 Arc<Mutex<Option<Box<MyStruct>>>>> 强制转换为 Arc<Mutex<Option<Box<dyn Trait>>>>> 将不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68240685/

相关文章:

rust - Cargo Clippy 抛出错误 'Question mark operator is useless here' - 建议可以实现吗?

parsing - 将十六进制字符串转换为十进制整数

rust - 如何将字符串列表缩写为最短、明确的形式

rust - 如何为UnixStream和TcpStream创建多态类型

generics - 使用泛型作为集合中函数​​的参数

testing - 如何在 Rust 的实现中测试方法

python - 为什么我无法执行来自 Process 的某些命令?

rust - 如何在自定义序列化和反序列化中使用 "flatten"之类的东西

rust - "does not live long enough"相同函数错误

rust - 如何撰写经向日志?