Add an operator overload for clone()

Calling multiple functions which take their parameters by reference is quite convenient:

foo(&a);
bar(&a);
baz(&a);

But if functions are defined via move semantics, one has to explicitly clone non-Copy types:

foo(a.clone());
bar(a.clone());
baz(a.clone());
bab(a);

Also consider the usage of the vec! macro, to create a Vec of cloned values:

let v = vec![foo.clone(), bar.clone(), baz.clone(), a.clone(), b.clone(), c.clone()]

The visual noise gets rather bad.
I suggest introducing an operator similar to * and & which clones the value.
Above examples but with + defined as the clone()-operator (+ just being a suggestion, any character would do):

foo(+a);
bar(+a);
baz(+a);
bab(a);
let v = vec![+foo, +bar, +baz, +a, +b, +c]

(copy of https://github.com/rust-lang/rfcs/issues/2350 )

1 Like

My view is that explicit cloning outside of generic T: Clone bounds can often be expensive operations because otherwise you just use Copy. This leads me to the view that cloning should be visible, more so than +x, and that .clone() is proper.

However, if things are getting repetitive, one can easily create a macro:

// haven't compiled this, but you get the idea..
macro_rules! vec_clone {
    ($($elt: expr),*) => { vec![ $( $elt.clone() ),* ] }
}

let v = vec_clone![foo, bar, baz, a, b, c];

This has the advantage of clarity of that cloning is happening and I believe even less tedious / repetitive compared to:

let v = vec![+foo, +bar, +baz, +a, +b, +c];
5 Likes

Plus, if String gets the optimisation of cow-like static string references and string literals get automatic coercion to those when needed, that handles something like 90% of the trivial cases when clone is a “necessary evil” that just looks bad.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.