How do I concatenate the following combinations of types:
str
and str
String
and str
String
and String
There are two ways to concatenate strings in Java: By + (String concatenation) operator. By concat() method.
In formal language theory and computer programming, string concatenation is the operation of joining character strings end-to-end. For example, the concatenation of "snow" and "ball" is "snowball".
When you concatenate strings, you need to allocate memory to store the result. The easiest to start with is String
and &str
:
fn main() { let mut owned_string: String = "hello ".to_owned(); let borrowed_string: &str = "world"; owned_string.push_str(borrowed_string); println!("{}", owned_string); }
Here, we have an owned string that we can mutate. This is efficient as it potentially allows us to reuse the memory allocation. There's a similar case for String
and String
, as &String
can be dereferenced as &str
.
fn main() { let mut owned_string: String = "hello ".to_owned(); let another_owned_string: String = "world".to_owned(); owned_string.push_str(&another_owned_string); println!("{}", owned_string); }
After this, another_owned_string
is untouched (note no mut
qualifier). There's another variant that consumes the String
but doesn't require it to be mutable. This is an implementation of the Add
trait that takes a String
as the left-hand side and a &str
as the right-hand side:
fn main() { let owned_string: String = "hello ".to_owned(); let borrowed_string: &str = "world"; let new_owned_string = owned_string + borrowed_string; println!("{}", new_owned_string); }
Note that owned_string
is no longer accessible after the call to +
.
What if we wanted to produce a new string, leaving both untouched? The simplest way is to use format!
:
fn main() { let borrowed_string: &str = "hello "; let another_borrowed_string: &str = "world"; let together = format!("{}{}", borrowed_string, another_borrowed_string); // After https://rust-lang.github.io/rfcs/2795-format-args-implicit-identifiers.html // let together = format!("{borrowed_string}{another_borrowed_string}"); println!("{}", together); }
Note that both input variables are immutable, so we know that they aren't touched. If we wanted to do the same thing for any combination of String
, we can use the fact that String
also can be formatted:
fn main() { let owned_string: String = "hello ".to_owned(); let another_owned_string: String = "world".to_owned(); let together = format!("{}{}", owned_string, another_owned_string); // After https://rust-lang.github.io/rfcs/2795-format-args-implicit-identifiers.html // let together = format!("{owned_string}{another_owned_string}"); println!("{}", together); }
You don't have to use format!
though. You can clone one string and append the other string to the new string:
fn main() { let owned_string: String = "hello ".to_owned(); let borrowed_string: &str = "world"; let together = owned_string.clone() + borrowed_string; println!("{}", together); }
Note - all of the type specification I did is redundant - the compiler can infer all the types in play here. I added them simply to be clear to people new to Rust, as I expect this question to be popular with that group!
To concatenate multiple strings into a single string, separated by another character, there are a couple of ways.
The nicest I have seen is using the join
method on an array:
fn main() { let a = "Hello"; let b = "world"; let result = [a, b].join("\n"); print!("{}", result); }
Depending on your use case you might also prefer more control:
fn main() { let a = "Hello"; let b = "world"; let result = format!("{}\n{}", a, b); print!("{}", result); }
There are some more manual ways I have seen, some avoiding one or two allocations here and there. For readability purposes I find the above two to be sufficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With