Any difference between these concatenation strategies?

Hello. Wondering the idiomatic way of concatenation in rust. Specifically, I am constructing a url based on some CLI command inputs.

#[derive(StructOpt, Debug)]
struct Cli {
    attributes: String,
    id: String,
}

fn main() -> Result<(), Error> {
    let args = Cli::from_args();

    let url = format!("http://swapi.dev/api/{}/{}", args.attributes, args.id);
    let url = String::from("http://swapi.dev/api/") + &args.attributes + "/" + &args.id;
    ... etc
}

Which one is idiomatic? Is there another way of doing this that is "better"?

If you're dealing with URLs specifically, it's probably best to use the url crate. You can use the Url::join method as necessary.

2 Likes

I hardly ever see the + operator used to concatenate strings in Rust.

Most people will use format!() if they're trying to interpolate variables, or some_string.push_str() if they want to add some more text to the end in an imperative way (imagine you're building up a string in a loop or something).

I've found you need to do this sort of string concatenation a lot less frequently in Rust than other languages. When you need to build up a string which should be in a particular format, Rust programmers will tend to create a strongly-typed wrapper which enforces the format (e.g. std::path::PathBuf for filesystem paths, or the url crate for URLs) whereas a Python or C++ programmer would use a normal string and remember how it's meant to be used.

3 Likes

For URLs, it's the url crate.

As for concatenation of strings in general, there are two most idiomatic approaches:

  • format!() if it's not performance critical
  • String::with_capacity() and s.push_str() if performance is critical (it's not much faster than format!(), so this makes sense only if you're doing lots of appending).
1 Like

If you have &strs already (or things that Deref to that, such as Strings), as it looks like you do here, then I suggest this way:

let x = ["A", " ", "simple", " ", "demo", "."].concat();

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=127fcf1c51ecc783d4fc64b28639d657

That way it's short to write, nice to read, and fully efficient -- it does the with_capacity+push_str thing that kornel mentioned internally.

EDIT: A previous conversation, which ironically also had both me and kornel...

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.