我正在尝试在 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>>>>`
看起来它无法存储 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/