Concat! literals

Yes, i really feel myself as a noob...

concat!("aaa", "bbb");

this works

let s1 = "aaa";
let s2 = "bbb"
concat!(s1, s2)

this does not work

why?
Thx as usual :slight_smile:

1 Like

Macros operate over the syntactic structure of the code. They don't evaluate the code. So concat!() really just concatenates string literals. Like, literally literals. It doesn't see through variables because macros are expanded way before the compiler even analyzes variables.

9 Likes

If you can have constants, you can try

Interesting... anyway

let s1 = "abc";
let s2 = "def";
let s3 = format!("{}{}", s1, s2);

this code seems fine for that job.
is the right way to concatenate two literals?

thx

If you want a String, you can also do

let s3 = [s1, s2].concat();
2 Likes

Here's an old thread on that: Best way to do string concatenation in 2019 (Status quo) - #5 by scottmcm

1 Like

Again, s1 and a2 are not literals. What is it you are trying to do?

1 Like

Nothing really important, i'm trying to understand something deeper about the language reporting some questions of the team working on Rust.
thx for the answers

If you just want to concatenate any string-valued expressions, then you can't use concat!() for that. You can use any of the previously mentioned options, they are all fine. (Obviously, if you have a variable number of concatenees, then format!() won't work as it needs a statically known number of arguments, but you can still use <[&str]>::concat(), String::push_str(), etc.)

1 Like

Rust is not executed in the order it's written. Macros are executed first, before everything else. Variables are created later. Rust runs this:

let s1 = "aaa";
let s2 = "bbb"
concat!(s1, s2)

in this order (pseudocode):

// early phase of compile-time:
const output_of_the_macro = concat!(s1, s2);
// later compile-time phase, and then at run-time:
let s1 = "aaa";
let s2 = "bbb";
output_of_the_macro

Therefore, macros can't act on values or even types of variables, because there are no variables in the program (yet) at the time the macros are run.

2 Likes

I believe since that thread, format!("{s1}{s2}") also works, though only for simple identifiers (eg "{user.name}" doesn't work)