如何将 Rc<RefCell<_>> 中的具体对象转换为动态特征对象? [复制]
Posted
技术标签:
【中文标题】如何将 Rc<RefCell<_>> 中的具体对象转换为动态特征对象? [复制]【英文标题】:How do I cast a concrete object in a Rc<RefCell<_>> to a dynamic trait object? [duplicate] 【发布时间】:2022-01-19 00:10:25 【问题描述】:我有实现ModifyValue
特征的结构MyText
。 MyText::new
返回Rc<RefCell<MyText>>
。
我想要一个结构Modifier
,给定Rc<RefCell<dyn ModifyValue>>
类型的喷射(实际上是任何实现特征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
)。
【问题讨论】:
看来Clone an Rc<RefCell<MyType> trait object and cast it的答案可能会回答您的问题; How do I cast Rc<RefCell<ConcreteType>> to Rc<RefCell<dyn Trait>>? 。如果没有,请edit您的问题来解释差异。否则,我们可以将此问题标记为已回答。 【参考方案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);
【讨论】:
以上是关于如何将 Rc<RefCell<_>> 中的具体对象转换为动态特征对象? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
Rc<RefCell<T>> 和 RefCell<Rc<T>> 有啥区别?
Rc<RefCell<T>> 和 RefCell<Rc<T>> 有啥区别?
Rayon 如何防止线程之间使用 RefCell<T>、Cell<T> 和 Rc<T>?