Deriving
Supported traits can be automatically implemented for your custom types, as follows:
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
#[derive(Debug, Clone, Default)]
struct Player {
name: String,
strength: u8,
hit_points: u8,
}
fn main() {
let p1 = Player::default(); // Default trait adds `default` constructor.
let mut p2 = p1.clone(); // Clone trait adds `clone` method.
p2.name = String::from("EldurScrollz");
// Debug trait adds support for printing with `{:?}`.
println!("{p1:?} vs. {p2:?}");
}
-
Derivation is implemented with macros, and many crates provide useful derive macros to add useful functionality. For example,
serdecan derive serialization support for a struct using#[derive(Serialize)]. -
Derivation is usually provided for traits that have a common boilerplate implementation that is correct for most cases. For example, demonstrate how a manual
Cloneimpl can be repetitive compared to deriving the trait:// Copyright 2023 Google LLC // SPDX-License-Identifier: Apache-2.0 impl Clone for Player { fn clone(&self) -> Self { Player { name: self.name.clone(), strength: self.strength.clone(), hit_points: self.hit_points.clone(), } } }Not all of the
.clone()s in the above are necessary in this case, but this demonstrates the generally boilerplate-y pattern that manual impls would follow, which should help make the use ofderiveclear to students.