Automatically print out EXPR = VALUE

Hello out there,

I'm very new to Rust with only a few weeks experience, coming from a professional C++ background. I'm quite excited about the borrow checker, the concurrency aids, and the overall clean appearance of the language. Rustdoc and the crates repository are great. This might be the language I am looking for. We'll see if I can convince my company to rewrite everything in Rust ... :wink:

While learning Rust and debugging my code, there is one feature I am missing: a = specifier for format strings, as I know it from Python.

I would like to be able to say

let answer = 42;
println!("{answer=}");

and it should output answer = 42.

This feature would save millions of Rust developers even more million hours of time they spend typing debugging/logging code.

The best I have come up with so far is to write a macro like this:

#[macro_export]
macro_rules! inspect {
  ($expr:expr) => {
    format!("{} = {:?}", stringify!($expr), $expr)
  };
}

which can be used this way:

let answer = 42;
println!("{}", inspect!(answer));

but this doesn't feel very comfortable, and it might have performance issues.

Is there a better way? Can i extend println! or format_args! in some magical way, or is there a place I could make a feature request?

I am aware of the dbg! macro, but it doesn't really fit my needs. I would prefer a general format-string solution I can use for printing and logging.

This is not a general solution since it doesn't have any output control, but for quick debugging you can use the dbg macro, which does print the variable names or expression source code along with their values.

5 Likes

For this specific solution, it would be a bit better if you used format_args! instead of format!, to not create an intermediate String. In this case, there should be no performance difference at all.

Feature requests are usually going through RFC process, and probably should be discussed beforehand on internals.rust-lang.org.

2 Likes

Related prior discussion with some links, etc.

3 Likes

tracing log events come with fields and associated shorthand.

let answer = 42;
// produces an event with one field, `answer`
tracing::debug!(answer);
// produces an event with two fields:
// - `answer` with value 42
// - `message` with value "answer calculation complete"
tracing::debug!(answer, "answer calculation complete");

This syntax is covered in the documentation I linked above.

log can also have fields in logs, but you have to enable the kv feature.

If you need to format it to a string, your inspect! macro works fine, and should have no performance cost if you replace format! with format_args!.

…And quinedot beat me to linking to the recent IRLO thread.

1 Like