Current guidance on &str to String (to_owned vs to_string)

Some of the 2015 guidance is out of date, but I don't think anything's changed substantially in the last few years here.

I still like this post from 2017 about it:

Here're some other previous conversations:

Personally, I distinguish between to_owned and clone more than I think most people do. I like using to_owned for all &T -> T things, even where clone would work, and instead keep clone for what I think of as T -> (T, T) things (even though Clone in implementation is also &T -> T).

As such, there are times when I'd use all of the options, depending what I'm doing:

  • If I already have a String, but need another one for a bit because I have to change it to give to something else, I'd .clone() it.
  • If I have a &str (or &String if that happened from an iterator adapter or something) that I need to edit, I'll use .to_owned() on it (same as I would if I had a &[u8] and wanted a Vec).
  • If something takes a name: String then I'll use .to_string() because the fact that it's a &str I'm starting with isn't important -- if it was a Uuid or u64 or something I'd do the same.
  • If I'm calling something else and don't really care, I'd likely just use .into(), like foo(s.into()), same as I'd do if I happen to have a u32 and it wants a u64 or something like that.

But I wouldn't say that's the modern convention, just my taste.

9 Likes