【问题标题】:How do I cast a concrete object in a Rc<RefCell<_>> to a dynamic trait object? [duplicate]如何将 Rc<RefCell<_>> 中的具体对象转换为动态特征对象? [复制]
【发布时间】:2023-04-01 07:15:01
【问题描述】:

我有实现ModifyValue 特征的结构MyTextMyText::new 返回Rc&lt;RefCell&lt;MyText&gt;&gt;

我想要一个结构Modifier,给定Rc&lt;RefCell&lt;dyn ModifyValue&gt;&gt; 类型的喷射(实际上是任何实现特征ModifyValue 的动态对象),知道如何调用给定对象的modify 方法。

use std::{cell::RefCell, rc::Rc};

trait ModifyValue {
    fn modify(&mut self, s: &String);
}

struct MyText {
    value: String,
}

impl MyText {
    pub fn new() -> Rc<RefCell<Self>> {
        Rc::new(RefCell::new(MyText {
            value: String::from("Hello world"),
        }))
    }
}

impl ModifyValue for MyText {
    fn modify(&mut self, s: &String) {
        self.value = s.clone();
    }
}

struct Modifier {
    what: Rc<RefCell<dyn ModifyValue>>,
}

impl Modifier {
    pub fn new(el: &Rc<RefCell<dyn ModifyValue>>) -> Self {
        Modifier {
            what: Rc::clone(el),
        }
    }

    pub fn modify(&self, new_val: &String) {
        Rc::clone(&self.what).borrow_mut().modify(new_val);
    }
}

fn main() {
    let txt = MyText::new();
    println!("{}", txt.borrow_mut().value);

    Rc::clone(&txt).borrow_mut().value = String::from("Bye Bye");
    println!("{}", txt.borrow_mut().value);

    Rc::clone(&txt)
        .borrow_mut()
        .modify(&String::from("Bye Bye, Hello world"));
    println!("{}", txt.borrow_mut().value);

    //// Problem here.
    let modifier = Modifier::new(&txt);
    /// Error .... !!!!!
    modifier.modify(&String::from("hola mundo"));
    //// ......

    println!("{}", txt.borrow_mut().value);
}

它给出了一个错误,我不能用它的特性动态地钩住对象txt。:

error[E0308]: mismatched types
  --> src/main.rs:55:34
   |
55 |     let modifier = Modifier::new(&txt);
   |                                  ^^^^ expected trait object `dyn ModifyValue`, found struct `MyText`
   |
   = note: expected reference `&Rc<RefCell<(dyn ModifyValue + 'static)>>`
              found reference `&Rc<RefCell<MyText>>`

如果我删除两个有问题的行,代码就可以工作。

在 C++ 中,我会使用纯虚拟类来执行此操作,但我无法在 Rust 中重现它(尤其是使用 Rc)。

【问题讨论】:

标签: dynamic rust traits rc refcell


【解决方案1】:

感谢这个话题的建议,我已经解决了:How do I cast Rc<RefCell<ConcreteType>> to Rc<RefCell<dyn Trait>>?

下面是我的解决方案:

use std::{cell::RefCell, rc::Rc};

trait ModifyValue {
    fn modify(&mut self, s: &String);
}

struct MyText {
    value: String,
}

impl MyText {
    pub fn new() -> Rc<RefCell<Self>> {
        Rc::new(RefCell::new(MyText {
            value: String::from("Hello world"),
        }))
    }

impl ModifyValue for MyText {
    fn modify(&mut self, s: &String) {
        self.value = s.clone();
    }
}

struct Modifier {
    what: Rc<RefCell<dyn ModifyValue>>,
}

impl Modifier {
    pub fn new(el: &Rc<RefCell<dyn ModifyValue>>) -> Self {
        Modifier {
            what: Rc::clone(el),
        }
    }

    pub fn modify(&self, new_val: &String) {
        Rc::clone(&self.what).borrow_mut().modify(new_val);
    }
}

fn main() {
    let txt = MyText::new();
    println!("{}", txt.borrow_mut().value);

    Rc::clone(&txt).borrow_mut().value = String::from("Bye Bye");
    println!("{}", txt.borrow_mut().value);

    Rc::clone(&txt)
        .borrow_mut()
        .modify(&String::from("Bye Bye, Hello world"));
    println!("{}", txt.borrow_mut().value);

    
    let txt_c = txt.clone() as Rc<RefCell<dyn ModifyValue>>;
    let modifier = Modifier::new(&txt_c);
    modifier.modify(&String::from("hola mundo"));

    println!("{}", txt.borrow_mut().value);
}

【讨论】:

    猜你喜欢
    • 2019-09-21
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    相关资源
    最近更新 更多