RustArena

Step 3 of 6

Joining text: format! and +

format!: println! that returns the text

format! takes the same format string and values as println! (with {}, {name}, {:.2} and {:?}), but instead of printing, it returns the result as a new String:

fn main() {
    let name = "Ana";
    let visits = 3;
    let msg = format!("Welcome back, {name}! Visit #{visits}");
    let price = format!("{:.2} EUR", 7.5);
    println!("{msg}");
    println!("{price}");
}
Welcome back, Ana! Visit #3
7.50 EUR

Use it whenever you need text built from values: messages, file names, IDs, report lines. It's the most common way to build strings in Rust.

Joining with +

You can also join strings with +:

fn main() {
    let first = String::from("Ada");
    let last = String::from("Lovelace");
    let full = first + " " + &last;
    println!("{full}");
    println!("{last}");
}
Ada Lovelace
Lovelace

+ has two rules that surprise everyone at first:

Because of those rules, many Rust programmers prefer format!("{first} {last}"): it reads like the result, and it leaves every variable usable.

Appending with +=

s += "text"; appends to s in place, just like s.push_str("text"). With a String on the right, add & again: s += &other;.

Common mistakes

fn main() {
    let a = String::from("Hello, ");
    let b = String::from("world");
    let c = a + b;
    println!("{c}");
}
error[E0308]: mismatched types

The message says expected `&str`, found `String` and suggests &b ("consider borrowing here"). Or write format!("{a}{b}").

Your task

Write greeting(name, visits). On the first visit (visits is 1) it returns Welcome, Ana!; on later visits it returns Welcome back, Ana! Visit #3 (with the real name and number).

Challenge 2

Write price_tag(item, cents), which returns text like coffee: $3.50. Prices are stored in whole cents, so price_tag("coffee", 350) returns "coffee: $3.50". Always show two decimals.

Challenge 3

Write countdown(n), which returns the numbers from n down to 1, separated by spaces, followed by liftoff!. For example countdown(3) returns "3 2 1 liftoff!" and countdown(0) returns "liftoff!".

Previous: Growing a String with push_str and push Next: Length: bytes versus characters