4 ms·
That's inaccurate. You can do what you describe as long as you use Rust's reference counting support (Rc and Arc), which includes weak references that can be u
by devit 10y ago
That's inaccurate.
You can do what you describe as long as you use Rust's reference counting support (Rc and Arc), which includes weak references that can be used for parent pointers, plus RefCell and Mutex for mutation.
To have an object "self-destruct", have it remove all reference counted pointers to itself.
You can pass an &Rc<Self> (or &Rc<RefCell<Self>> or &Arc<Mutex<Self>>) as the self parameter if you want to let an object create references to itself. If you want an object to be able to drop itself immediately in that case, use an Rc<Self> instead of an &Rc<Self>, and call drop(self) in the method (this also work if you are not using reference counting and just pass Self, of course).
You should try to not do this kind of thing though, because it adds overhead and the compiler cannot statically check that you are not leaking reference counted cycles or deadlocking on mutexes or refcells (which is not a Rust limitation, it's just impossible without having the programmer write a machine-checkable proof).
If you do it in C++ the compiler also cannot check whether you are referencing freed memory or incorrectly concurrently modifying the same object.
- oconnor663 10y agoI think Rc<RefCell<T>> falls into the "high boilerplate workarounds" category that ambrop7 mentioned they were trying to avoid.
- vertex-four 10y agoUsing an Rc<RefCell<T>> comes down to one method call, .borrow_mut() - it's not exactly magic, but it's far from significant boilerplate either. Additionally, it's not a "workaround", it's an inherent part of most useful Rust code. Servo contains 79 uses of borrow_mut.
- Manishearth 10y agoNote that Servo has a GC (the spidermonkey one) since it deals with a managed DOM, so it is an atypical example. Most Rust code I've seen has far less RefCell usage; but yes, RefCell is pretty idiomatic and the boilerplate is minimal.
- Argorak 10y agoThere's a lot of stuff in Rust that makes such types manageable. Also, such types should always be expressed as: struct MyFancySharedThing<T> { thing: Rc<RefCell<T>> } Rc and RefCell are implementation details and should _always_ be hidden.
- tree_of_item 10y agoRc<RefCell<T>> is not high boilerplate at all, and it's a super common Rust pattern. If you think this is too much boilerplate then I'm really not sure what you were expecting. It's just composition of reference counting memory management and mutability, a great example of modular design. What more did you want?
- ambrop7 10y agoRc is dynamic memory allocation, which means every element of your application will end up in its dynamic memory block. This is inefficient and highly undesirable for resource-restricted / embedded applications.
- tree_of_item 10y agoRight, you shouldn't reflexively use Rc everywhere. That seems like a completely different topic, though: what I was responding to was the assertion that composition of Rc and RefCell was "boilerplate".
- Bromskloss 10y ago> You should try to not do this kind of thing though Is there a recommendation on what to do instead?