What is right ways to concat Strings?


#1

Using Trait std::slice::SliceConcatExt got an error of “use of unstable library feature ‘slice_cocat_ext’: trai should not have to exist”

Using as_str also got an error of “unsable”.


#2

I think the idiomatic way is to use format!("{}{}", a, b), or if one of them is a literal string anyway to use format!("bla{}blub", a). If you just want to extend a String by some characters you can use a.push_str("hello").


#3

Thank you for your comments!

My target is string, not str, so when I do “a.push_str(b.as_str())”, I got an error…

format!("{}{}", a, b) may be a nice hack, but concatenating strings is a very fundamental operation, I do not like hacking for it.

I think that if there are no simple ways for such fundamental operations, a language can not attract many people.

Thank you again.


#4

You can:

let mut foo = "foo".to_string();
let bar = "bar".to_string();
let baz = "baz".to_string();

// & is key
foo.push_str(&bar);

println!("{}", foo);
// same here
println!("{}", foo + &baz);

playpen

As listed above, format! also works.


#5

O_O

I am shocked!
It is simple, but I can not read it from documentation…

Rust is more like adventure game;-)

Thank you so much!


#6

It’s not a hack, in case you want to put a string into an arbitrary complex other string you can do format!("Hi my name is {}! And there's {} available", a, b) to insert the strings a and b into the first argument to format


#7

This line is also quite important for foo.push_str, as foo must be marked as mutable.

One nice thing about the macros is that this isn’t needed.


#8

Sorry for my unclear words.
What I want to say was that concatenating is more primitive than formatting. So I said, concateneting using formatting is kind of hack.^^


#9

I’d this not a situation where concat! would be used?


#10

O_O
Does concat! also work with Strings?
I was thinking that it is for str literals.

I cannot read it from the documentation.

Rust’s documentation is pretty kind but sometimes hard to understand simple things.


#11

No, the documentation is correct there.

Trying to use concat! without a literal gives you:

<anon>:3:35: 3:38 error: expected a literal
<anon>:3     println!("{}", concat!("foo", foo));

#12

Ah yeah, my bad. I shouldn’t comment suggestions just after waking up it seems.


#13

Usage of + as a concatenation operator isn’t universally popular and some people would like to remove it citing the fact that add isn’t exactly concatenation. The fact that people think that makes it unlikely that string + string will be implemented reasonably soon. This might also keep it from being documented since it isn’t the official way.

Also, the order is important. The left most value must be a string and all others must be &str.


#14

[a, b].concat() is stable, and it generalizes to multiple strings: [a, b, c, d].concat().

It also has the advantage over format!() that concat computes the exact size needed beforehand, so it allocates an exact sized string and does copying very efficiently.

The only problem is the type inference issue. You may have to force the operands to be &str.

concat is to format!() what String::from is to .to_string(), in a way :smile:

See also concat's sibling .join(separator: &str).


#15

I am confused.
I certainly tried concat method, and failed because of unstability of std::slice::SliceConcatExt .
Now I succeeded concat without std::slice::SliceConcatExt.

What trait implements concat?


#16

The trait is SliceConcatExt.

The trait itself is marked unstable, but the methods are not! It’s in the prelude so it doesn’t need to be imported.


#17

I will make sure it because I tried in my module, not in crate root.

Thank you!