简体   繁体   English

trait upcast coercion workaround 是如何工作的(获取 supertrait 实例的 trait 方法)?

[英]How does the trait upcast coercion workaround work (trait method for getting an instance of the supertrait)?

It looks like Rust does not allow using a reference to an instance of a trait to be used where a reference to an instance of the supertrait was expected:看起来 Rust 不允许在需要引用超特征实例的地方使用对特征实例的引用:

trait Animal{}
trait Dog: Animal{}

fn convert(dog: &Dog) -> &Animal {
    dog // Error: trait upcasting coercion is experimental, see issue #65991 ...
}

But there's a workaround, used often in the Rust-Analyzer codebase .但是有一种解决方法,经常在Rust-Analyzer 代码库中使用。 How does the workaround work?解决方法如何工作?

Here's the workaround, which enables us to write a convert that rustc will accept:这是解决方法,它使我们能够编写rustc将接受的convert

trait Animal{}
trait Dog: Animal{
    fn upcast(&self) -> &Animal; // added line
}
fn convert(dog: &Dog) -> &Animal {
    dog.upcast() // changed line
}

And here's an implementation of upcast :这是upcast的一个实现:

struct Foo {}
impl Animal for Foo {}
impl Dog for Foo {
    fn upcast(&self) -> &Animal {
        self
    }
}

Comparing the upcast and the original convert : they have the same signature and same implementation (modulo renaming).比较upcast和原始convert :它们具有相同的签名和相同的实现(模重命名)。 So it looks like something is allowed for methods that is not allowed for functions.因此,对于函数不允许的方法,似乎允许某些东西。 What happened?发生了什么?

&self in upcast() is not &dyn Dog , it is the concrete &Foo . upcast()中的&self不是&dyn Dog ,而是具体的&Foo This is usual call to a method of a dyn Trait .这是对dyn Trait方法的通常调用。

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

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