Help with understanding print!() with string literal

i am not able to understand why

    let s = "hello";
    print!("{}", s);

works but not this:

    let s = "hello";
    print!(s);

s is storing a string literal according to my understanding. the same thing works well in C's printf() but not working here.

can anyone help me in this regard?

thank you.

it's because, print! is a macro, not a function. and it requires the format string to be a literal known at compile time.

No, it doesn't. It stores a &'static str. The string literal is the thing with the double quotes (including those) and only exists at compile time.

i almost got that understanding but i was not really sure. Thank you for the clarification

To expand a bit, you can write your own macros that only accept literals (playground):

macro_rules! takes_literal {
    ($foo:literal) => { dbg!($foo); }
}

fn main() {
    takes_literal!("foo"); // [src/main.rs:7:5] "foo" = "foo"

    let foo = "foo";
    takes_literal!(foo);   // does not compile

    const FOO: &str = "foo";
    takes_literal!(FOO);   // does not compile either
}

although it's not possible to implement a print-like macro from scratch yourself, as it needs compiler support to parse and validate the format string.

although it's not possible to implement a print-like macro from scratch yourself, as it needs compiler support to parse and validate the format string.

Sorry to nitpick, but the format_args! macro is available if you need to format "hello {a} {:2}" style strings. println! expands to include format_args!, though format_args! itself is a compiler builtin.

And if you need to parse a more complex syntax, you can use a proc macro which can perform completely arbitrary transformations to your Rust code.

Which is why I said "from scratch" :slight_smile: As in, without using the compiler-provided formatting machinery.