我觉得很奇怪
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(使用前将#替换为@)