3 ms·
RAII really is a brilliant design, it both (mostly) solves the problem of manual memory management and is easier (for my brain at least) to reason about than de
by smitherfield 9y ago
RAII really is a brilliant design, it both (mostly) solves the problem of manual memory management and is easier (for my brain at least) to reason about than deterministic (shared_ptr, Obj-C/Swift) or nondeterministic (managed langs) garbage collection schemes. Once I grokked it I've never looked at managed langs the same way again.
In C++'s defense it's not like the language or the compilers encourage you to use shared_ptr, but it's also true (mainly for legacy C-interop cruft) it doesn't do enough to nudge you to write code in a proper RAII style, nor to enforce correctness WRT ownership.
I like that Rust forces you to explicitly opt out of RAII and/or single-owner semantics. (Those are the "defaults" in C++ too, but too easy to implicitly or accidentally opt out of). On the other hand you can write Java in any language, and from the little Rust I've read, newcomers from managed langs will often daisy-chain enough smart pointers in a row to put any 13-year-old who just downloaded Unreal Engine to shame.
The last time I took a serious look at Rust I thought it took things too far in the other direction; you weren't able to use two (nonoverlapping!) data members of the same struct in a function, and the suggested workaround was to wrap it in a smart pointer. Has that issue been fixed now?
- vvanders 9y ago> The last time I took a serious look at Rust I thought it took things too far in the other direction; you weren't able to use two (nonoverlapping!) data members of the same struct in a function, and the suggested workaround was to wrap it in a smart pointer. Has that issue been fixed now? I think that's largely been addressed. Are you talking about doing something like this? https://play.rust-lang.org/?gist=cf5835d28946df6c5093d57b7ca0aba1&version=stable https://play.rust-lang.org/?gist=cf5835d28946df6c5093d57b7ca...
- smitherfield 9y agoIt's long enough ago I can't remember exactly what I was trying to do except that it was trivially correct, but yeah I think that was it. Anyway, I'm glad that's been solved; looks like I've got some new weekend plans! :)
- vvanders 9y agoAwesome :). Something else to keep in mind that while it's nice to have the borrow-checker validate everything it's okay to step around it if you've got a case that's gnarly and you know is valid. I've had some C callback stuff where I run into that occasionally, I can't encode the lifetime semantics to the calling function so I have to side-step it. In that case things like RefCell(which are separate from (A)Rc/Box) are a great "escape hatch". Obviously you should try and keep it to a minimum but don't let it be a complete roadblock.
- Sharlin 9y agoClosures still borrow whole structs from the captured scope when they could only borrow the fields they actually need: https://play.rust-lang.org/?gist=26b2efa859589a8172cad982f0dfb89b&version=stable https://play.rust-lang.org/?gist=26b2efa859589a8172cad982f0d... This is especially frustrating when it's self that is being captured. There's an accepted RFC for fixing this but I'm not sure when it's going to be implemented.
- vvanders 9y agoYou can work-around that by capturing the fields you need individually. It's a little awkward but does let you express what you're trying to do there: https://play.rust-lang.org/?gist=2463ff559d7f96f916d246272b19ff68&version=stable https://play.rust-lang.org/?gist=2463ff559d7f96f916d246272b1... Agreed that it's not the best default behavior though. Generally I tend to try to keep unrelated things in separate structs for this reason(with the nice side benefit of keeping concerns separate).
- adrianratnapala 9y agoI agree the example looks "obviously" correct. But my paranoia worries that an aggressive optimiser might write to bytes next to the actual fields in ways that render the code incorrect. While that worry sounds insane, it is exactly the kind of thing C compilers have retroactively defined as Undefined Behaviour. So kudos to Rust for having the compiler tell you up front where it reserves the right to do stupid stuff in future.