How do I pass Rc>> to a function accepting Rc>>?

前端 未结 1 538
滥情空心
滥情空心 2020-12-19 06:49

I have originally asked this question here, but it was marked as duplicate, although it duplicates only a part of it in my opinion, so I have created a more specific one:

1条回答
  •  無奈伤痛
    2020-12-19 07:50

    (An older revision of this answer essentially advised to clone the underlying struct and put it in a new Rc> object; this was necessary at the time on stable Rust, but since not long after that time, Rc> will coerce to Rc> without trouble.)

    Drop the Box<> wrapping, and you can coerce Rc> to Rc> freely and easily. Recalling that cloning an Rc just produces another Rc, increasing the refcount by one, you can do something like this:

    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>) {
        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> instead of Rc>,
        // essentially doing the coercion one step earlier.)
        let my_str: Rc> = Rc::new(RefCell::new(MyStruct1));
        my_trait_fn(my_str.clone());
        my_str.borrow().my_fn();
    }
    

    As a general rule, see if you can make things take the contained value by reference, ideally even generically—fn my_trait_fn(t: &T) and similar, which can typically be called as my_str.borrow() with automatic referencing and dereferencing taking care of the rest—rather than the whole Rc> thing.

    0 讨论(0)
提交回复
热议问题