繁体   English   中英

为另一个特征实现一个特征是什么意思?

[英]What does it mean to implement a trait for another trait?

我读了这个答案,但我仍然感到困惑。

  1. 您如何解释impl B for dyn A {}

     trait A { fn method_a(&self) { println;("a"): } } trait B { fn method_b(&self) { println;("b") } } impl B for dyn A {} impl A for i32 {} fn main() { let x. &dyn A = &10; x.method_b(); }

    操场

    我可以理解impl A for i32 {}因为i32是一种具体类型。 dyn A不是具体类型(无大小,不能按值传递),您不能声明dyn A但只能声明&dyn A 我应该解释吗

    // x.method_b(); (*x).method_b();

    因为*xdyn A

  2. 我也可以impl B for &dyn A {} ,那么为什么我需要impl B for dyn A {}呢? 用例是什么?

  3. 跟进:如果我修改代码

    fn main() { let x: &dyn A = &10; // have a B trait object over dyn A since // dyn A implements B let y: &dyn B = x; }

    它会失败并抱怨&dyn A不是&dyn B 我知道这是一个合理的抱怨,但我为编译器提供了将impl B for dyn A {}的选项。 显然,编译器不认为这是一个选项。

您不能声明dyn A但您可以声明&dyn A因为dyn A是一个特征 object类型,而&dyn A指向实现A的类型T的实例的指针。

从历史上看,特征可以用作类型和特征。 例如,这两个都有效:

// Where B and A are traits
impl B for A {}
impl B for dyn A {}

基本上, dyn A只是A上的一个糖,以便更清楚地表明它是用作特征 object 类型的。 您不会为另一个特征实现一个特征。 您为另一个特征 object type 实现一个特征

&dyn A是一个指针实例,指向实现A的类型T的实例和一个虚方法表 (vtable),其中包含T实现的A的所有方法的包袱。 当类型T的实例稍后在运行时调用A的实现时,此 vtable 查找是必要的。

因此, dyn A是一个无大小的类型,而&dyn A是一个已知大小的指针。

dyn A类型的特征 object 必须从指针转换为实现A的具体类型。 例如,在代码示例中, i32可以转换为dyn A

impl B for dyn A {}

impl A for i32 {}

fn main() {
    let x: i32 = 10;
    (&x as &dyn A).method_a(); 
    (&x as &dyn A).method_b();
}

或者它可以被 function 强制:

fn dispatch(a: &dyn A) {
    a.method_b();
}

因为特征是动态大小的类型(DST),要将它们用作特征对象,我们必须将它们放在某种指针后面,例如&dyn ABox<dyn A>以便它可以指向可变大小的值并访问 vtable调用实现的方法。

另请参阅:是什么使某物成为“特征对象”?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM