A derive macro asks Rust to implement a trait for a type automatically. Write `#[derive(Debug)]` immediately above a struct or enum to give it `Debug`, which lets you print it with `{:?}`. The `#[...]` syntax is an attribute: a message to the compiler about the item that follows. section 4.1.5 section 7.1
#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Clone)]
struct HoldsAString {
the_string: String,
}
fn main() {
let my_string = HoldsAString {
the_string: "Here I am!".to_string(),
};
println!("{:?}", my_string);
}
This struct requests several trait implementations in one `derive` attribute. The final line uses its derived `Debug` implementation to print the value. section 13.1.5
Deriving saves you from writing an implementation yourself when Rust can supply one. `Debug`, for example, needs a `fmt` method, but you will usually derive it rather than write that method. You can also derive `Clone` and `Copy` for the small struct shown in the attributes examples. section 13.1.4 section 13.1.5
When derive does not work
Trying `#[derive(Display)]` in the shown example produces `cannot find derive macro Display in this scope`. Not every trait can be derived: Rust cannot guess what adding two values of a custom type should mean, so `Add` needs a manual `impl`. section 13.1.5 section 7.1
#[derive(Clone, Debug)]
struct File(String);
impl std::fmt::Display for File {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let as_bytes = format!("{:?}", self.0.as_bytes()); #1
write!(f, "{as_bytes}")
}
}
fn main() {
let file = File(String::from("I am file contents"));
println!("{file:?}");
println!("{file}");
}
A wrapper around `String` does not automatically gain `String`’s traits. Here it derives `Clone` and `Debug`, while `Display` gets a handwritten implementation. section 7.4




