dos*_*pro 3 casting smart-pointers rust trait-objects
这是来自不同 taits 之间的 Rust dynamic cast trait object的后续问题。当我们对 trait 对象使用引用时,那里提供的解决方案非常有效,但这次我试图用Rc指针做同样的事情。例如
TraitAB和 2 个名为TraitA和的特征TraitBTraitAB而不是使用 a 时Box,现在我使用了一个Rc指针。TraitA作为参考ab在这里,我做了一个非常小的例子:
use std::rc::Rc;
trait TraitAB: TraitA + TraitB {
fn as_a(&self) -> Rc<dyn TraitA>;
fn as_b(&self) -> Rc<dyn TraitB>;
}
trait TraitA {}
trait TraitB {}
struct MyType {}
impl TraitAB for MyType {
fn as_a(&self) -> Rc<dyn TraitA> {
Rc::clone(self)
}
fn as_b(&self) -> Rc<dyn TraitB> {
Rc::clone(self)
}
}
impl TraitA for MyType {}
impl TraitB for MyType {}
fn main() {
let a: Rc<dyn TraitA>;
let b: Rc<dyn TraitB>;
{
let mut ab: Rc<dyn TraitAB> = Rc::new(MyType {});
a = ab.as_a();
b = ab.as_b();
}
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用。根据错误信息:
error[E0308]: mismatched types
--> src/main.rs:15:19
|
15 | Rc::clone(self)
| ^^^^ expected struct `std::rc::Rc`, found struct `MyType`
|
= note: expected reference `&std::rc::Rc<dyn TraitA>`
found reference `&MyType`
error[E0308]: mismatched types
--> src/main.rs:18:19
|
18 | Rc::clone(self)
| ^^^^ expected struct `std::rc::Rc`, found struct `MyType`
|
= note: expected reference `&std::rc::Rc<dyn TraitB>`
found reference `&MyType`
Run Code Online (Sandbox Code Playgroud)
as_a并且as_b不能知道 self 实际上是一个Rc指针。有没有办法对克隆的共享指针进行强制转换?
方法
as_a和as_b不能知道 self 实际上是一个Rc指针。
事实上,这不是真的!还有一个很少使用的功能,它允许self采取各种标准的各类参考文献(的Rc<Self>,Box<Self>等等)。
这意味着你可以重写你TraitAB的
trait TraitAB : TraitA + TraitB {
fn as_a(self: Rc<Self>) -> Rc<dyn TraitA>;
fn as_b(self: Rc<Self>) -> Rc<dyn TraitB>;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,正如所写的那样,as_a并且as_bmove self: Rc<Self>,因为Rc<T> 没有实现Copy(仅Clone)。解决此问题的一种方法是ab在将其传递给这些方法之前简单地进行克隆。这也意味着您不需要克隆self方法内部。(游乐场链接)
let ab: Rc<dyn TraitAB> = Rc::new(MyType{});
let _a: Rc<dyn TraitA> = ab.clone().as_a();
let _b: Rc<dyn TraitB> = ab.clone().as_b();
Run Code Online (Sandbox Code Playgroud)
使用 nightly-only 功能arbitrary_self_types,可以将 self 设为as_a和as_b获取&Rc<Self>(这对我来说看起来很奇怪,因为它是对参考的引用)。这允许ab.as_a()在不移动的情况下调用ab。这种方法的唯一问题TraitAB 是不再是对象安全的1,因此Rc<dyn TraitAB>不再有效。(游乐场链接)。
| 归档时间: |
|
| 查看次数: |
601 次 |
| 最近记录: |