Первоначально я задавал этот вопрос здесь, но он был отмечен как повторяющийся , хотя, на мой взгляд, он дублирует только его часть, поэтому я создал более конкретный:
Рассмотрим следующий код:
use std::rc::Rc;
trait MyTrait {
fn trait_func(&self);
}
struct MyStruct1;
impl MyStruct1 {
fn my_fn(&self) {
// do something
}
}
impl MyTrait for MyStruct1 {
fn trait_func(&self) {
// do something
}
}
fn my_trait_fn(t: Rc<dyn MyTrait>) {
t.trait_func();
}
fn main() {
let my_str: Rc<MyStruct1> = Rc::new(MyStruct1);
my_trait_fn(my_str.clone());
my_str.my_fn();
}
Этот код работает нормально. Теперь я хочу изменить определение trait_func
, чтобы принять &mut self
, но это не сработает, поскольку Rc
работает только с неизменяемыми данными. Решение, которое я использую, - обернуть MyTrait
в RefCell
:
use std::cell::RefCell;
fn my_trait_fn(t: Rc<RefCell<Box<dyn MyTrait>>>) {
t.borrow_mut().trait_func();
}
fn main() {
let my_str: Rc<RefCell<Box<MyStruct1>>> = Rc::new(RefCell::new(Box::new(MyStruct1)));
my_trait_fn(my_str.clone());
my_str.my_fn();
}
При компиляции получаю сообщение об ошибке:
error[E0308]: mismatched types
--> src/main.rs:27:17
|
27 | my_trait_fn(my_str.clone());
| ^^^^^^^^^^^^^^ expected trait MyTrait, found struct `MyStruct1`
|
= note: expected type `std::rc::Rc<std::cell::RefCell<std::boxed::Box<dyn MyTrait + 'static>>>`
found type `std::rc::Rc<std::cell::RefCell<std::boxed::Box<MyStruct1>>>`
= help: here are some functions which might fulfill your needs:
- .into_inner()
Как лучше всего решить эту проблему?
Rc<MyTrait>
, ваш второй код использует дополнительныйBox
, который необходим только в стабильной версии. БезBox
ваш код работает нормально по ночам с небольшими изменениями: is.gd/zQUJqp. Пожалуйста, отредактируйте свой вопрос, если вам нужно решение для стабильной ржавчины. - person oli_obk   schedule 16.06.2015Box
кажется решением моей проблемы. Я думаю, что возможностьRefCell
работать напрямую с Trait была недавно представлена, поэтому она изначально не работала для меня (когда я обновлял свой ночной Rust около 2 недель назад). - person Dmitry Uvarov   schedule 16.06.2015