9.10 Derived Traits and Common Operations

Traits define shared behavior. Rust’s #[derive] attribute automatically implements common traits, enabling standard operations on structs.

Commonly derived traits include:

  • Debug: Enables printing structs using {:?} (debug format). Essential for debugging. For user-facing output, implement the Display trait manually.
  • Clone: Enables creating deep copies via .clone(). Requires all fields to be Clone.
  • Copy: Enables implicit bitwise copying on assignment, function calls, etc. Structs can only be Copy if all their fields are also Copy. Assignment (let y = x;) moves x if the type is not Copy, but copies x if it is Copy.
  • PartialEq, Eq: Enable comparison (==, !=). Requires all fields to implement the respective trait(s).
  • PartialOrd, Ord: Enable ordering (<, >, etc.). Requires all fields to implement the respective trait(s).
  • Default: Enables creation of default instances. (Covered earlier).
  • Hash: Allows use in hash maps/sets. Requires all fields to be Hash.

Example Enabling Operations:

// Deriving traits enables common operations
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct SimplePoint {
    x: i32,
    y: i32,
}

fn main() {
    let p1 = SimplePoint { x: 1, y: 2 };
    let p2 = p1; // **Assignment**: Copies p1 because SimplePoint is Copy

    let p3 = p1.clone(); // **Cloning**: Explicitly creates a copy

    println!("Debug print: {:?}", p1); // **Printing (Debug)**

    println!("Comparison: p1 == p2 is {}", p1 == p2); // **Comparison** (PartialEq)
    println!("Ordering: p1 < p3 is {}", p1 < p3);    // **Ordering** (PartialOrd)

    use std::collections::HashSet;
    let mut points = HashSet::new();
    points.insert(p1); // **Hashing** (Hash + Eq required for HashSet)
    println!("Set contains p1: {}", points.contains(&p1));
}

Deriving traits is idiomatic for providing standard behaviors concisely. Manually implementing traits offers customization when needed.