派生特征

系统可以自动为您的自定义类型实现支持的 trait,如下所示:

#[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:?}");
}
This slide should take about 3 minutes.
  • 派生功能是通过宏实现的,并且许多 crate 提供有用的派生宏,以添加实用功能。例如,serde 可以使用 #[derive(Serialize)] 为结构体派生序列化支持。

  • Derivation is usually provided for traits that have a common boilerplate-y implementation that is correct for most cases. For example, demonstrate how a manual Clone impl can be repetitive compared to deriving the trait:

    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 of derive clear to students.