[英]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.