I'm not against smart pointers where they make sense, it's just whenever I see them I start bracing myself for the horrors that seem to inevitably follow.
I'm not against smart pointers where they make sense, it's just whenever I see them I start bracing myself for the horrors that seem to inevitably follow.
It's also why I really like that Rust decided to go RAII/single-ownership and add a ton of friction(via RefCell) to make sure that you really want shared ownership. It forces you to get your house in order up-front which I've found almost always leads to a better design overall.
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?
I think that's largely been addressed. Are you talking about doing something like this?
https://play.rust-lang.org/?gist=cf5835d28946df6c5093d57b7ca...
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.
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.
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).
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.