通过派生 trait 增加实用功能
如果能够在调试程序时打印出 Rectangle 实例来查看其所有字段的值就更好了。如下示例像前面章节那样尝试使用 println! 宏。但这并不行。
文件名: src/main.rs
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("rect1 is {}", rect1);
}
当我们运行这个代码时,会出现带有如下核心信息的错误:
error[E0277]: `Rectangle` doesn't implement `std::fmt::Display`
println! 宏能处理很多类型的格式,不过,{} 默认告诉 println! 使用被称为 Display 的格式:意在提供给直接终端用户查看的输出。目前为止见过的基本类型都默认实现了 Display,因为它就是向用户展示 1 或其他任何基本类型的唯一方式。不过对于结构体,println! 应该用来输出的格式是不明确的,因为这有更多显示的可能性:是否需要逗号?需要打印出大括号吗?所有字段都应该显示吗?由于这种不确定性,Rust 不会尝试猜测我们的意图,所以结构体并没有提供一个 Display 实现。
但是如果我们继续阅读错误,将会发现这个有帮助的信息:
= help: the trait `std::fmt::Display` is not implemented for `Rectangle`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
让我们来试试!现在 println! 宏调用看起来像 println!("rect1 is {:?}", rect1); 这样。在 {} 中加入 :? 指示符告诉 println! 我们想要使用叫做 Debug 的输出格式。Debug 是一个 trait,它允许我们以一种对开发者有帮助的方式打印结构体,以便当我们调试代码时能看到它的值。
这样调整后再次运行程序。见鬼了!仍然能看到一个错误:
error[E0277]: `Rectangle` doesn't implement `Debug`
不过编译器又一次给出了一个有帮助的信息:
= help: the trait `Debug` is not implemented for `Rectangle` = note: add `#[derive(Debug)]` to `Rectangle` or manually `impl Debug for Rectangle`
Rust 确实包含了打印出调试信息的功能,不过我们必须为结构体显式选择这个功能。为此,在结构体定义之前加上外部属性 #[derive(Debug)],如下所示:
文件名: src/main.rs
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("rect1 is {:?}", rect1);
}
现在我们再运行这个程序时,就不会有任何错误,并会出现如下输出:
$ cargo run
Compiling rectangles v0.1.0 (file:///projects/rectangles)
Finished dev [unoptimized + debuginfo] target(s) in 0.48s
Running `target/debug/rectangles`
rect1 is Rectangle { width: 30, height: 50 }
详情查看:https://www.rustwiki.org.cn/zh-CN/book/ch05-02-example-structs.html