3 ms·
> I'd clone to convince the borrow checker to let me move on, would construct new containers rather than pass new ones in to be refilled and the like. Also, st
by chias 10y ago
> I'd clone to convince the borrow checker to let me move on, would construct new containers rather than pass new ones in to be refilled and the like. Also, strings. Lots and lots of strings everywhere.
This is where I'm at right now. When the borrow checker yells at me, I find I can generally fix it with a .clone() or a .to_string(). I'm new enough with the borrow checker that I'm not quite sure when such cloning is necessary and when I'm unnecessarily allocating more memory -- or more importantly, what I should be doing instead when it's not necessary -- but I hope that as I write more code, I'll get better at it :)
A bad habit that I've fallen into is to needlessly allocate in order to avoid having to think about lifetimes. As in, better change that struct to make that str a String -- and then not have to worry about lifetimes at all. That's just laziness, though...
- akiselev 10y agoThis is the going advice many Rustaceans give to beginners. Cloning something in Rust is nothing like cloning in dynamic languages where you need to notify a garbage collector and allocate heap memory. Rust is fast and copying data is fast, especially if you're cloning a stack only value to satisfy the borrow checker. Make it work, then make it correct, then make it fast. Chances are you'll never need that last step for most code you write. Edit: another thing you'll learn with practice is when to make the right trade offs. Rust has lots of types in the standard library that allow you to pick and choose which guarantees you want the compiler to uphold and whether to do it at compile time or run time. Check out "Choosing your Guarantees" in the new version of the rust book [1] [1] https://doc.rust-lang.org/beta/book/choosing-your-guarantees.html https://doc.rust-lang.org/beta/book/choosing-your-guarantees...
- dbaupp 10y agoCloning anything nontrivial (String, Vec, structs containing them, which is when cloning is usually used to ease things) does need to allocate. The comparison to managed languages doesn't make sense: "notifying the GC" sounds exactly like "notifying the memory allocator" in Rust/C/C++.
- akiselev 10y agoI should have said "as long as" instead of "especially when." When you're cloning a data structure, obviously you need to think about what you're cloning, no matter what language you do it in, and you need to know the difference between Copy and Clone. My point is that a cloning operation is still fast and modern processors are well optimized for it as long as the library author didn't put some computationally expensive or blocking operation. You have to "notify the memory allocator" in every language but in Rust you don't pay for the extra GC overhead unless you explicitly opt into RC, Arc, or your own GC. The point is that in a low level language, allocating and copying to maintain safety guarantees is fine because you have finr grained control over what you pay for. For a beginner, it's more important to get a feel for the borrow checker and cloning allows someone to get a positive feedback loop until they figure out how to structure their code to work with the borrow checker instead of against it.
- dbaupp 10y agoOne of the benefits of some common GC algorithms is how efficient it is to allocate (for most allocations), meaning the GC overhead is small and possibly negative. I don't think comparing the (throughput) performance of doing allocations is where Rust wins in a convincing way: any major benefits come because the language makes it easier to avoid them totally, as you imply. In any case, the most common things people clone when learning are strings and vectors, where cloning is an O(length) operation (allocation plus copying the data), which doesn't avoid any allocation overhead and I would think counts as computationally expensive. (Notably, in managed languages with immutable strings, Rust's copies are significantly more expensive, since the former can copy in O(1).) Cloning is definitely a perfectly good way to get started, but it shouldn't be dressed up as something it's not nor should Rust itself.
- steveklabnik 10y agoClone runs arbitrary Rust code; there's no way to say how expensive or not it is. That's one reason it's never called implicitly.