4

See this example:

fn concat<T: std::fmt::Display>(s: &mut String, thing: T) {
    // TODO
}

fn main() {
    let mut s = "Hello ".into();
    concat(&mut s, 42);

    assert_eq!(&s, "Hello 42");
}

I know that I can use this:

s.push_str(&format!("{}", thing))

but this is not the most efficient, because format! allocate a String that is not necessary.

The most efficient is to write directly the string representation of the displayable item into the String buffer. How to do this?

0

1 Answer 1

7

There are multiple formatting macros, and in your case you want the write! macro:

use std::fmt::{Display, Write};

fn concat<T: Display>(s: &mut String, thing: &T) {
    write!(s, "{}", thing).unwrap();
}

fn main() {
    let mut s = "Hello ".into();
    concat(&mut s, &42);

    assert_eq!(&s, "Hello 42");
}

Anything that implements one of the Write trait (and String does) is a valid target for write!.

Note: actually anything that implements a write_fmt method, as macro don't care much about semantics; which is why either fmt::Write or io::Write work.

Sign up to request clarification or add additional context in comments.

2 Comments

There are two (usable) Write traits (std::io and std::fmt).
@Stefan: Yes. I didn't feel like calling it out explicitly since it's mentioned in the write! macro documentation that I linked, but since you felt the need for it, it now is :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.