![](/img/trans.png)
[英]Downcasting a Rc<RefCell<Box<struct>>> to Rc<RefCell<Box<dyn trait>>>
[英]How do I pass Rc<RefCell<Box<MyStruct>>> to a function accepting Rc<RefCell<Box<dyn MyTrait>>>?
我最初在這里問了這個問題,但它被標記為重復,雖然它在我看來只復制了它的一部分,所以我創建了一個更具體的一個:
請考慮以下代碼:
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<RefCell<Box<MyTrait>>
對象;這在穩定Rust的時候是必要的,但是在那之后不久, Rc<RefCell<MyStruct>>
將Rc<RefCell<MyStruct>>
強制轉到Rc<RefCell<MyTrait>>
。)
放下Box<>
包裝,你可以輕松地將Rc<RefCell<MyTrait>>
強制Rc<RefCell<MyStruct>>
為Rc<RefCell<MyTrait>>
。 回想克隆一個Rc<T>
只產生另一個Rc<T>
,將refcount增加一,你可以這樣做:
use std::rc::Rc;
use std::cell::RefCell;
trait MyTrait {
fn trait_func(&self);
}
#[derive(Clone)]
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<RefCell<MyTrait>>) {
t.borrow_mut().trait_func();
}
fn main() {
// (The type annotation is not necessary here, but helps explain it.
// If the `my_str.borrow().my_fn()` line was missing, it would actually
// be of type Rc<RefCell<MyTrait>> instead of Rc<RefCell<MyStruct1>>,
// essentially doing the coercion one step earlier.)
let my_str: Rc<RefCell<MyStruct1>> = Rc::new(RefCell::new(MyStruct1));
my_trait_fn(my_str.clone());
my_str.borrow().my_fn();
}
作為一般規則,看看你是否可以通過引用來獲取所包含的值,理想情況下甚至通常是fn my_trait_fn<T: MyTrait>(t: &T)
和類似的,通常可以自動調用my_str.borrow()
參考和解除引用照顧其余的 - 而不是整個Rc<RefCell<MyTrait>>
事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.