5 ms·
Would it be better to combine both types (e.g. a MutRc<T> type), and get rid of Cell/RefCell?
by azth 12y ago
Would it be better to combine both types (e.g. a MutRc<T> type), and get rid of Cell/RefCell?
- pcwalton 12y agoI don't think so, because then you'd get an overconservative iterator invalidation checker. For example: struct Foo { a: Vec<int>, b: Vec<int>, } let foo = Rc::new(RefCell::new(Foo::new(...))); for x in foo.borrow_mut().a.mut_iter() { for y in foo.borrow_mut().b.mut_iter() { // ^^^ FAILURE: a is already borrowed mutably } } The failure happens because the RefCell is checking to make sure there are no two `&mut` references at the same time to `Foo`, to prevent iterator invalidation. But this is silly, because it only needs to prevent access to `a` while you're iterating over it, not both `a` and `b`. Changing the definition of `Foo` to this fixes the problem: struct Foo { a: RefCell<Vec<int>>, b: RefCell<Vec<int>>, }
- azth 12y agoMakes sense. Though Cells would really stand out in the code as a potential for race conditions (unless you get a run time failure?). Thanks for the insight.
- pcwalton 12y agoThere is a special bound--Share--that is required on thread-safe data structures and forbids Cell/RefCell. The thread-safe equivalents of Cell and RefCell are Atomic and Mutex, respectively.