What is the difference between println's forma

2019-01-27 23:17发布

问题:

I'm so sorry to ask such a simple question... A day ago, I started learning Rust and tried the println! method.

fn main() {
  println!("Hello {}!", "world");
}
-> Hello world!

And then, I found other format styles: {}, {:}, {:?}, {?}, ...

I know that {} is instead String, but I don't understand the other format style. How do those styles differ from each other? I think {:?} is array or vector. Is it correct?

Please explain these format style with sample code :(

回答1:

For thoroughness, the std::fmt formatting syntax is composed of two parts:

{<position-or-name>:<format>}

where:

  • <position-or-name> can be the argument position: println!("Hello {0}!", "world");`, note that it is checked at compile-time
  • <position-or-name> can also be a name: println!("Hello {arg}!", arg = "world");
  • <format> is one of the following formats, where each format requires the argument to implement a specific trait, checked at compile-time

The default, in the absence of position, name or format, is to pick the argument matching the index of {} and to use the Display trait. There are however various traits! From the link above:

  • nothing ⇒ Display
  • ? ⇒ Debug
  • o ⇒ Octal
  • x ⇒ LowerHex
  • X ⇒ UpperHex
  • p ⇒ Pointer
  • b ⇒ Binary
  • e ⇒ LowerExp
  • E ⇒ UpperExp

and if necessary new traits could be added in the future.



回答2:

println!() is a macro that uses the std::fmt syntax and {} indicate parameters. If the brackets are left empty ({}), the corresponding argument needs to implement the Display trait and if they contain :? it means that the argument's Debug implementation should be used instead.

The bottom line is that it is not the parameters' type that is relevant here, but the traits they implement. For instance, Vectors implement Debug, but they don't implement Display and that is why you can't use {} against them while {:?} works just fine.



标签: rust