Reputation: 123
Like following code, it does working to print values with formatted print, when values are primitive values or struct(with derive debug attribute), or something. But I can't print values when values are struct fields.
#[derive(Debug)]
struct Point<T> {
x: T,
y: T,
}
fn main() {
let a = 3;
let p = Point { x: 5, y: 10 };
println!("{}", a); // Working
println!("{a}"); // Working
println!("{:?}", p); // Working
println!("{p:?}"); // Working
println!("{} {}", p.x, p.y); // Working
println!("{p.x} {p.y}"); // Not working
}
The error message is following.
error: invalid format string: expected `'}'`, found `'.'`
--> src/main.rs:18:17
|
18 | println!("{p.x} {p.y}"); // Not working
| - ^ expected `}` in format string
| |
| because of this opening brace
|
= note: if you intended to print `{`, you can escape it using `{{`
error: could not compile `rust-ex` due to previous error
I think that the type of p.x and p.y is i32 so they can printed with formatted print but it doesn't. Is there any way to print struct fields with formatter print? Or is there anything need to implement?
Upvotes: 12
Views: 3598
Reputation: 21074
Another similar but different issue is trying to println!
when you have a Rust variable that is an underscore:
let _ = 2;
println!("Value of _ is {_}");
The error is:
invalid format string: invalid argument name `_`
...
println!("Value of _ is {_}");
^ invalid argument name in format string
This is probably because the underscore is meant to be ignored
The underscore (_) is a reserved identifier in Rust and serves different purposes depending on the context. It usually means that something is ignored.
Other sites explain how in rust, the underscore does "not bind to the variable"; or "does not have ownership of the object"
See @jthulhu's comment --not only is _
meant to be ignored in Rust, the _
variable cannot be used in Rust; therefore isn't even allocated (that explains my error messages). This is different from other programming languages, where the _
variable is just a convention to signify the _
variable is meant to be ignored but could be used. In Rust, as @jthulhu says: "Basically, doing let _ = 3
; will result in absolutely nothing even without optimizations"
I know the OP already found the best accepted answer. I just want to offer this answer in case other folks search for "invalid format string" or "invalid argument name _
" and find this SO question.
If you tried a workaround like:
println!("Value of _ is {}", _);
Then you get a new error, reinforcing the idea that the underscore variable is never meant to be used:
in expressions, `_` can only be used on the left-hand side of an assignment
`_` not allowed here
So the underscore variable is allowed on the left-hand side of an assignment as in my code above, or this underscore expression where the _
signifies a placeholder in a destructuring assignment, but you can't reference the underscore variable later, including in println!
. The only solution is to use a different variable name.
Upvotes: 2
Reputation: 8678
Your problem is not a formatting problem, just an issue with what exactly println!
accepts in its formatting string.
Contrary to what you may experience in other languages, the part between braces in the literal string in a println!
is not a string escape, meaning that you could put any (printable) Rust expression. Instead, you should see it as a named parameter. Therefore, it can only be a variable name. println!
also allows you to mimic variable definition if you don't already have a variable with that name, like this:
println!("{px}", px = p.x);
Upvotes: 13