How does RefCell clone work?

Clone trait for RefCell is implemented by self.borrow().clone(). borrow() returns Ref and Ref has a associated function clone() to be used as Ref::clone() and Clone trait has not been implemented for Ref. How does self.borrow().clone() this work then? I know that Ref has two fields- one of type &T and other BorrowRef (and BorrowRef implements Clone trait)-but I am still confused.

Also why is separate Ref::clone() needed?

The implementation is:

impl<T: Clone> Clone for RefCell<T> {
    fn clone(&self) -> RefCell<T> {
        RefCell::new(self.borrow().clone())
    }
}

self.borrow() gives Ref<T>, but Ref<T> doesn't implement Clone trait, so the compiler searches further its Deref for a thing to clone, and finds that it can clone T this way.

Ref::clone() is needed, because there's intentionally no <Ref as Clone>::clone() method. If there was then you'd need (*cell.borrow()).clone() to get T, because the simpler cell.borrow().clone() would give you just another Ref<T>, which isn't helpful.

1 Like