Is there any way to avoid calling .to_string()
when I need a string? For example:
fn func1(aaa: String) -> ....
And instead of
func1("fdsfdsfd".to_string())
can I do something like this:
func1(s"fdsfdsfd")
Is there any way to avoid calling .to_string()
when I need a string? For example:
fn func1(aaa: String) -> ....
And instead of
func1("fdsfdsfd".to_string())
can I do something like this:
func1(s"fdsfdsfd")
TL;DR:
As of Rust 1.9, str::to_string
, str::to_owned
, String::from
, str::into
all have the same performance characteristics. Use whichever you prefer.
The most obvious and idiomatic way to convert a string slice (&str
) to an owned string (String
) is to use ToString::to_string
. This works for any type that implements Display
. This includes string slices, but also integers, IP addresses, paths, errors, and so on.
Before Rust 1.9, the str
implementation of to_string
leveraged the formatting infrastructure. While it worked, it was overkill and not the most performant path.
A lighter solution was to use ToOwned::to_owned
, which is implemented for types that have a "borrowed" and an "owned" pair. It is implemented in an efficient manner.
Another lightweight solution is to use Into::into
which leverages From::from
. This is also implemented efficiently.
For your specific case, the best thing to do is to accept a &str
, as thirtythreeforty answered. Then you need to do zero allocations, which is the best outcome.
In general, I will probably use into
if I need to make an allocated string — it's only 4 letters long ^_^. When answering questions on Stack Overflow, I'll use to_owned
as it's much more obvious what is happening.
No, the str::to_string()
method is the canonical way of creating a String
from an &'static str
(a string literal). I even like it for the reason you dislike it: it's a little verbose. Because it involves a heap allocation, you should think twice before invoking it in cases such as these. Also note that since Rust gained impl specialization, str::to_string
is no slower than str::to_owned
or its ilk.
However, what you really want here is a func1
that can easily be passed any string, be it a &str
or a String
. Because a String
will Deref to a &str
, you can have func1
accept an &str
, thereby avoiding the String allocation altogether. See this example (playground):
fn func1(s: &str) {
println!("{}", s);
}
fn main() {
let allocated_string: String = "owned string".to_string();
func1("static string");
func1(&allocated_string);
}
I now strongly prefer
to_owned()
for string literals over either ofto_string()
orinto()
.What is the difference between
String
and&str
? An unsatisfactory answer is “one is a string and the other is not a string” because obviously both are strings. Taking something that is a string and converting it to a string usingto_string()
seems like it misses the point of why we are doing this in the first place, and more importantly misses the opportunity to document this to our readers.The difference between String and &str is that one is owned and one is not owned. Using
to_owned()
fully captures the reason that a conversion is required at a particular spot in our code.
struct Wrapper {
s: String
}
// I have a string and I need a string. Why am I doing this again?
Wrapper { s: "s".to_string() }
// I have a borrowed string but I need it to be owned.
Wrapper { s: "s".to_owned() }
Not if you mentally read
to_string
asto_String
https://users.rust-lang.org/t/to-string-vs-to-owned-for-string-literals/1441/6?u=rofrol