0

我有MyText实现ModifyValue特征的结构。MyText::new返回Rc<RefCell<MyText>>

我想要一个结构Modifier,给定一个类型的 jet Rc<RefCell<dyn ModifyValue>>(实际上是任何实现 trait 的动态对象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.

4

1 回答 1

1

由于这个主题的建议,我已经解决了:如何将 Rc<RefCell<ConcreteType>> 转换为 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);
}
于 2021-12-16T07:50:04.937 回答