Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 将弧克隆到弧中,其中T实现U_Rust_Polymorphism - Fatal编程技术网

Rust 将弧克隆到弧中,其中T实现U

Rust 将弧克隆到弧中,其中T实现U,rust,polymorphism,Rust,Polymorphism,我觉得这很奇怪 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::Ar

我觉得这很奇怪

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克隆Arc的较短变体?

这是类型推断在Rust中如何工作的结果。方法Arc::clone接受&Arc。编译器需要确定T是什么

在第一个代码段中,编译器对Arc::clone&pear的返回类型没有任何约束,因此它根据传入的参数推断t。参数的类型为&Arc,因此编译器推断T=Pear。代码段中的最后一行隐式地执行从一个弧到另一个弧的非大小强制

在第二个代码段中,编译器已经知道所需的返回类型Arc::clone&pear,因为目标变量包含类型注释。在此基础上,编译器推断出T=dyn水果,并期望参数类型为&Arc。但是,它会找到一个&Arc,它不能强制为所需的类型,因此编译器会出错

类型推断在Rust中如何工作的细节目前还没有完全说明。每当编译器未推断出正确的类型时,应添加显式类型提示:

let pear = Arc::new(Pear {});
let cloned_casted: Arc<dyn Fruit> = Arc::<Pear>::clone(&pear);
编译器可以推断uu表示弧,但它不再知道从什么类型进行强制转换,因此它需要以与在第一个代码段中相同的方式推断该类型

另见:


除了Sven Marnach的变体,我们还可以

    let cloned_casted: Arc<dyn Fruit> = pear.clone();

隐式铸造,也请记住,铁锈的特点不是界面。这种形式的唯一问题是不清楚你是想克隆弧线还是克隆梨。这就是为什么编写Arc::clone很常见的原因——它让读者知道您的意思,并告诉编译器,如果您将任何非Arc的内容放在那里,这应该是一个错误。
    let cloned_casted: Arc<dyn Fruit> = pear.clone();