Rust有四种向控制台输出的方式,分别为format!()
,print!()
,println!()
,dbg!()
。
前三种打印操作定义在std::fmt
里面
用法如下:
let a = "myself";
format!("this is {}",&a);
println!("this is {:?}",&a);
println!("this is {}",&a);
print!("this is {}",&a);
dbg!(&a);
[Running: cargo run --message-format=json]
Compiling study v0.1.0 (/home/banapy/projects/study)
Finished dev [unoptimized + debuginfo] target(s) in 0.60s
Running `target/debug/study`
this is "myself"
this is myself
[src/main.rs:7] &a = "myself"
this is myself[Finished in 0.7s]
std::fmt中包含多种trait来控制文字的显示,这里面有两个重要的基本格式类型如下:
-
fmt::Debug
使用 {:?} 作标记。格式化文本以便调试。 -
fmt::Display
使用 {} 作标记。以优雅和友好的方式来格式文本。
自己实现该trait
对于自定义的结构体,只有它实现以上两种trait之一时,才能被打印
//#[derive(Debug)]
struct Student {
name: String,
year:u8,
}
impl Student{
fn new(a:&str,b:u8)->Self{
Self{
name:a.to_string(),
year:b,
}
}
}
fn main(){
let x = Student::new("xiaoming",18);
println!("{:?}", &x);
}
此时会报错
error: src/main.rs:17: `Student` doesn't implement `std::fmt::Debug`
error: src/main.rs:17: `Student` cannot be formatted using `{:?}`
为其实现std::fmt::Debug
和std::fmt::Display
特性
use std::fmt;
//#[derive(Debug)]
struct Student {
name: String,
year:u8,
}
impl Student{
fn new(a:&str,b:u8)->Self{
Self{
name:a.to_string(),
year:b,
}
}
}
impl fmt::Debug for Student{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Student {{ x: {}, y: {} }}", self.name, self.year)
}
}
impl fmt::Display for Student{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.name, self.year)
}
}
fn main(){
let x = Student::new("xiaoming",18);
println!("{:?}", &x);
}
[Running: cargo run --message-format=json]
Compiling study v0.1.0 (/home/banapy/projects/study)
Finished dev [unoptimized + debuginfo] target(s) in 0.74s
Running `target/debug/study`
Student { x: xiaoming, y: 18 }
(xiaoming, 18)
就是说,当Student
实现std::fmt::Debug
时,能使用println!("{:?}",x)
执行打印操作。
把//#[derive(Debug)]
的//
去掉时能自动为Student
实现std::fmt::Debug
特性。
神奇吧!这是宏的一种,属于过程宏中的自定义宏,而println!()
为类函数宏。用户也能使用关键字macro_rules!
自定义宏,这称为声明宏。