The original problem was the bad ergonomics when cloning things into a closure, because one also needs to introduce a binding holding a variable often named very similar to the original.
The suggestion by @scottmcm of extending move
with a list of how variables are captured solves this issue perfectly (at least in my eyes).
Other situations (when needing to clone something a lot) do not have this ergonomic problem of requiring you to create a binding for each clone. You might need to write .clone()
a couple of times, but I think the explicit call has multiple benefits:
- easily scan for uses of
clone
using text search - no implicitly executed code
-
clone
is not special, it is just another function (drop
on the other hand is special)
While a binding marker like autoclone
would improve this situation I think it is unnecessary in the face of better ergonomics for specifying closure capturing.
I am firmly against introducing an AutoClone
Trait (because it executes non-special code implicitly), when I come across cloning data, it is one of these situations:
- I want to turn a reference into something that i own (should be explicit)
- I need to pass the same data to multiple functions (should be explicit)
- I need to pass the same data to multiple threads (should be explicit, but without the additional let bindings)
I have not yet seen an example where autoclone
/AutoClone
would be useful (prevent a lot of clone
calls) that is not situation 3 (because there it would also get rid of the additional bindings).
When you really have such extensive usage of clone
(situation 1 & 2), why not use a closure to clone your data?
let data = ...;
let data = || data.clone();
consume(data());
consume(data());
consume(data());
consume(data());
consume(data());
consume(data());
consume(data());
consume(data());
consume(data());
consume(data());
Aside from the additional ()
and creation of the closure, this is identical to the autoclone
/AutoClone
syntax. But you still have the clone call to find with text search and the explicit closure call indicating that some code is run there.