to_string
method creates a String
from a string literal (&str
), just like what String::from
does:
let data = "initial contents";
let s = data.to_string();
// the method also works on a literal directly:
let s = "initial contents".to_string();
push_str
appends a string slice to a String
; on the contrary, push
append a single character.
let mut s1 = String::from("foo");
let s2 = "bar";
s1.push_str(s2);
println!("s2 is {}", s2); // we can still use s2 because push_str does not take ownership
let mut s = String::from("lo");
s.push('l');
We can use +
or format!
macro to concatenate strings.
The +
operator uses the add
method, whose signature looks something like this:
fn add(self, s: &str) -> String
add
will take ownership of self
and the right-hand side operand should be a &str
&s2
is of type &String
). Why? let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used
deref coersion
for us, turns &s2
into &s2[..]
. But note that String
does not support indexing, so if it was not [..]
but [i]
, it won’t compile at all.The format!
macro is more concise, and it takes references of its arguments, so s1
, s2
, s3
below still owns data after format!
call.
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = format!("{}-{}-{}", s1, s2, s3);
Rust strings don’t support indexing.
When using ranges to create string slices, code it with caution because it might crash your programs.
For individual Unicode scalar values, use the chars
method. Calling chars
on “नमस्ते” separates out and returns six values of type char
, and you can iterate over the result to access each element: