What is the most idiomatic way to convert a &str
to a String
?
Some options are:
What is the most idiomatic way to convert a &str
to a String
?
Some options are:
I use String::from for static strings and to_owned() for others, but I've never thought hard about it. Looking at the options is giving me self-doubt.
Don't forget "hello".into()
!
to_string
just calls String::from
, and String::from
just calls to_owned
. They're all inlined, so there's no performance cost to any of them. Format might be more expensive since it goes through all of the formatting abstractions.
As far as I'm aware, there's no performance difference between them, so use whichever you feel like.
If anything, the more interesting question is where those methods come from and why String
has both of 'em. to_owned()
is there because String
implements std::borrow::ToOwned and to_string()
comes from std::string::ToString.
The latter is particularly interesting, because the ToString
trait is actually implemented for anything that implements Display
. So you can do .to_string() on an i32
or on an Ipv4Addr
or on your own type that you've implemented Display
for.
Let's go over what each of these means semantically:
to_owned
: I have a borrowed object and I want an owned versionto_string
: I want the textual representation of somethinginto
(or String::from
): I want a generic type conversionformat!
: I want a textual representation of something in a particular representation. Basically a fancy way of calling to_string (to_string is implemented generically for Display, the canonical way of using Display is through format!)I think in most cases what you mean to do is to_owned
. into
is fine but conveys less intent. In cases where the type can be inferred, for example as a function argument, I think into
is fine.
Don't use format!
if you can use to_string
, less overhead.
I'd say pick the one that best expresses the context in which you're trying to use it:
to_owned
if you need a stronger level of access to itto_string
if you really want a string in particular.into()
if you're calling a function that needs something not quite what you haveI use only .to_owned()
. I believe it is better to stick with a single option everywhere, if there are multiple equivalent choices. Among these choices, String::from
is the most specific, but it's a mouthful to write and prefix, so I stick with .to_owned
as the next one most specific.
As for idiomaticness, I believe there are two "warring camps" of "use .to_string()
because it's simpler to teach", and "use .to_owned()
because it is semantically more frugal"
IIRC there was a time in the past when to_string wasn't specialized, so to_owned was suggested because it was faster at the time. They're now both the same speed, though.
Kinda bummed to_owned
wasn't chosen, since it helps you understand the distinction between str
and String
, as @dtolnay pointed out in his linked comment.