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 aVec
). - 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 aUuid
oru64
or something I'd do the same. - If I'm calling something else and don't really care, I'd likely just use
.into()
, likefoo(s.into())
, same as I'd do if I happen to have au32
and it wants au64
or something like that.
But I wouldn't say that's the modern convention, just my taste.