Add std::clone::CloneTo trait?

It seems surprising, but I couldn't find anything like this in libstd:

pub trait CloneTo<T> {
    fn clone_to(self) -> T;
}
impl<T: Clone> CloneTo<T> for T {
    fn clone_to(self) -> T {
        self
    }
}
impl<'a, T: Clone> CloneTo<T> for &'a T {
    fn clone_to(self) -> T {
        self.clone()
    }
}

Usage:

// accept &X or X:
fn foo<T: CloneTo<X>>(&mut self, x: T) {
    let _: X = x.clone_to();
}

It may seem like std::borrow::ToOwned (which would be a better name), but:

  1. ToOwned::to_owned takes &self, which does not permit usage without cloning
  2. ToOwned uses a type parameter over associated type, though I believe both would work in this case

This looks like Into, except being a bit more explicit that it might clone/be expensive

4 Likes

There's always Cow.

But generally, if you always need ownership inside a method, you should just take the parameter via ownership. Otherwise it's super easy for them to pass a borrow when they didn't need to.

The caller can just call .clone() if needed.

2 Likes

Yes, that does the same job semantically; this just allows the caller nicer syntax (and is a mostly-backwards-compatible change coming from function call with move or reference syntax, modulo type inference).