These are all forms of string interpolation and concatenation, but the 'go to' way is using string formatting, e.g. `printf("Hello %s", username)` (or `sprintf` to just return the resulting string instead of print it to stdout).
It doesn't add additional syntax (and therefore complexity, compiler steps, build time, etc) to the language; the only convenience applied here is varargs for the arguments besides the first.
A lot of languages started with basic (s)printf and added string interpolation later on, but that brings its own headaches. I'm thinking of PHP, where on the one hand you can do "hello $username", but if it's a property in an object you need to add additional syntax already - "hello {$user->name}".
Rust already does that. Just that sprintf("Hello %s", username) is written format!("Hello {}", username), which made it easy to now extend it to allow format!("Hello {username}"). Being a late comer made it easy to plan ahead for the future.
But really I didn't really mention it because printf syntax seems to me like exactly the "mini script using in-band signaling and its weird syntax" that GP complained about.
And it's important to note that format (and its relatives) is a macro and not a function. That means that whatever the input syntax is for format, whether you write format!("Hello {}", username) or format!("Hello {username}") it will compile as (something like) "Hello ".to_string() + username (as an aside, I really appreciate the fact that Rust macros are syntactically distinct entities so that you can tell at a glance whether you're doing a function call or something potentially strange is happening by way of a macro).
In contrast, the old-school stdio sprintf (and relatives) will interpret the format string at run time and then read a varargs list to do the interpolation which can lead to run-time errors and buffer-overflow vulnerabilities and so forth.
It doesn't add additional syntax (and therefore complexity, compiler steps, build time, etc) to the language; the only convenience applied here is varargs for the arguments besides the first.
A lot of languages started with basic (s)printf and added string interpolation later on, but that brings its own headaches. I'm thinking of PHP, where on the one hand you can do "hello $username", but if it's a property in an object you need to add additional syntax already - "hello {$user->name}".