How do I push_str the contents of a variable?

 let mut some_string = String::from("Hello");
 let x: u8 = 10;
some_string.push_str(format!(" {}"), x); // Not allowed!

I wanted to push 10 inside the some_string variable. I can't seem to use the format!() macro for some reason. How come with print!() macro it allows this but not the format!() macro?

    use std::fmt::Write;

    let mut some_string = String::from("Hello");
    let x: u8 = 10;
    write!(some_string, " {}", x).unwrap();

Playground

2 Likes

you could also write

some_string.push_str(&format!(" {}"), x);

format! gives you a String, so you need to take a reference to that to get a &str.

However this allocates a new String just to throw it away after it copied to some_string.
write! directly writes to some_string

4 Likes

Also, the x would need to be passed to format! instead of push_str:

some_string.push_str(&format!(" {}", x));
3 Likes

So do you mean that format!() allocates new string data and stores it somewhere on the heap? Is that why you used the & so that it will return the ptr instead to the push_str() function?

Sorry what do you mean by this?

Ah I didn't realise that. Thanks for pointing that out.

This code does the same:

// allocate a new String and write the formatted result into it
let temp_string = format(" {}", x);

// get a `&str` reference to it
let temp_str = temp_string.as_str();

// actually append it
some_string.push_str(temp_str);

// drop it
drop(temp_string);
1 Like

Thanks man, one last question, what does the unwrap() function do to the write!() macro?

edit: I don't seem to need it as this seems to work just fine?

write!(writer, "format string", argsā€¦) returns a Result, in case the writer fails.
However a String writer never fails (at least I think so), so unwrap is fine.

You can pass a file, bufwriter and many other things to it as well. Those can fail.

1 Like

The string won't cause a failure, but the thing you're printing can do so if the Display or Debug impl fails.

2 Likes

Of course a much simpler way would be to just:

   let mut some_string = String::from("Hello");
   some_string.push_str(&10.to_string());

It may be simpler, but it is less efficient due to a memory allocation, which may or may not matter to you.

format!() allocates too, no?

Yes, but using write! directly on the string does not make an extra allocation.

Huh, live and learn, I guess

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.