簡體   English   中英

我如何通過Rc <RefCell<Box<MyStruct> &gt;&gt;接受Rc的功能 <RefCell<Box<dyn MyTrait> &gt;&gt;?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM