Debug School

rakesh kumar
rakesh kumar

Posted on

How drive attribute auto-generates trait implementations

Why derive is needed (Theory)

[derive(...)] tells Rust to auto-generate implementations of common traits for your type, like:

Debug (so you can print with {:?})

Clone (so you can copy values)

PartialEq (so you can compare with ==)

Default (so you can create default values)
Enter fullscreen mode Exit fullscreen mode
how to print your struct (Debug)

how to compare (PartialEq, Eq, Ord)

how to copy (Clone, sometimes Copy)

how to create default values (Default)

how to use as key in HashMap (Hash)
Enter fullscreen mode Exit fullscreen mode

This saves a lot of boilerplate.

Different kinds of derive in Rust (most used)

Full Rust program (covers all derives)

use std::collections::{HashMap, HashSet};

// 1) Debug, 2) Clone, 3) PartialEq/Eq, 5) Hash, 6) Default
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
struct User {
    name: String,
    age: u32,
}

// 4) PartialOrd/Ord for sorting
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
struct Score(i32);

// 2) Copy example (cheap copy type)
#[derive(Debug, Copy, Clone, PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    println!("--- Debug + Default ---");
    let u_default = User::default();
    println!("default user = {:?}", u_default);

    println!("\n--- Clone ---");
    let u1 = User { name: "Ashwani".to_string(), age: 30 };
    let u2 = u1.clone();
    println!("u1 = {:?}", u1);
    println!("u2 = {:?}", u2);

    println!("\n--- PartialEq + Eq ---");
    println!("u1 == u2 ? {}", u1 == u2);

    println!("\n--- Hash (HashSet / HashMap keys) ---");
    let mut set = HashSet::new();
    set.insert(u1.clone());
    set.insert(u2.clone()); // duplicate, will not add again
    println!("HashSet size (should be 1) = {}", set.len());

    let mut map: HashMap<User, String> = HashMap::new();
    map.insert(u1.clone(), "Premium".to_string());
    println!("User tier = {}", map.get(&u1).unwrap());

    println!("\n--- PartialOrd + Ord (Sorting) ---");
    let mut scores = vec![Score(90), Score(50), Score(75), Score(75)];
    scores.sort(); // ascending
    println!("sorted scores = {:?}", scores);

    println!("\n--- Copy (no .clone needed) ---");
    let p1 = Point { x: 10, y: 20 };
    let p2 = p1; // copy happens
    println!("p1 = {:?}, p2 = {:?}", p1, p2);

    // show that p1 still usable (because Copy)
    let p3 = p1;
    println!("p3 = {:?}", p3);
}
Enter fullscreen mode Exit fullscreen mode

Output (Rust)

--- Debug + Default ---
default user = User { name: "", age: 0 }

--- Clone ---
u1 = User { name: "Ashwani", age: 30 }
u2 = User { name: "Ashwani", age: 30 }

--- PartialEq + Eq ---
u1 == u2 ? true

--- Hash (HashSet / HashMap keys) ---
HashSet size (should be 1) = 1
User tier = Premium

--- PartialOrd + Ord (Sorting) ---
sorted scores = [Score(50), Score(75), Score(75), Score(90)]

--- Copy (no .clone needed) ---
p1 = Point { x: 10, y: 20 }, p2 = Point { x: 10, y: 20 }
p3 = Point { x: 10, y: 20 }

Java comparison (what equals “derive”?)

Java has no built-in derive like Rust.
You must manually implement:

toString() (Debug)

equals() / hashCode() (PartialEq/Eq/Hash)

copying (Clone or copy constructor)

sorting (Comparable)

default values (constructors)
Enter fullscreen mode Exit fullscreen mode

Java records reduce boilerplate but still not as flexible as Rust derive.

Full Java program (similar behavior)

import java.util.*;

public class Main {

    static class User {
        String name;
        int age;

        User() { this.name = ""; this.age = 0; } // Default
        User(String name, int age) { this.name = name; this.age = age; }

        // Debug equivalent
        public String toString() { return "User{name='" + name + "', age=" + age + "}"; }

        // PartialEq + Eq + Hash equivalents
        @Override public boolean equals(Object o) {
            if (!(o instanceof User)) return false;
            User other = (User) o;
            return Objects.equals(this.name, other.name) && this.age == other.age;
        }
        @Override public int hashCode() { return Objects.hash(name, age); }

        // Clone/copy (recommended: copy constructor)
        User(User other) { this.name = other.name; this.age = other.age; }
    }

    static class Score implements Comparable<Score> {
        int value;
        Score(int value) { this.value = value; }

        @Override public int compareTo(Score o) {
            return Integer.compare(this.value, o.value);
        }

        public String toString() { return "Score(" + value + ")"; }
    }

    static class Point {
        int x, y;
        Point(int x, int y) { this.x = x; this.y = y; }
        public String toString() { return "Point{x=" + x + ", y=" + y + "}"; }
    }

    public static void main(String[] args) {
        System.out.println("--- toString + default constructor ---");
        User uDefault = new User();
        System.out.println("default user = " + uDefault);

        System.out.println("\n--- Copy (clone-like) ---");
        User u1 = new User("Ashwani", 30);
        User u2 = new User(u1);
        System.out.println("u1 = " + u1);
        System.out.println("u2 = " + u2);

        System.out.println("\n--- equals ---");
        System.out.println("u1 equals u2 ? " + u1.equals(u2));

        System.out.println("\n--- HashSet / HashMap keys ---");
        Set<User> set = new HashSet<>();
        set.add(new User(u1));
        set.add(new User(u2)); // duplicate
        System.out.println("HashSet size (should be 1) = " + set.size());

        Map<User, String> map = new HashMap<>();
        map.put(u1, "Premium");
        System.out.println("User tier = " + map.get(u1));

        System.out.println("\n--- Sorting (Comparable) ---");
        List<Score> scores = Arrays.asList(new Score(90), new Score(50), new Score(75), new Score(75));
        Collections.sort(scores);
        System.out.println("sorted scores = " + scores);

        System.out.println("\n--- Reference copy (no Copy trait in Java) ---");
        Point p1 = new Point(10, 20);
        Point p2 = p1; // reference copy (not deep copy)
        System.out.println("p1 = " + p1 + ", p2 = " + p2);
    }
}
Enter fullscreen mode Exit fullscreen mode

Output (Java)

--- toString + default constructor ---
default user = User{name='', age=0}

--- Copy (clone-like) ---
u1 = User{name='Ashwani', age=30}
u2 = User{name='Ashwani', age=30}

--- equals ---
u1 equals u2 ? true

--- HashSet / HashMap keys ---
HashSet size (should be 1) = 1
User tier = Premium

--- Sorting (Comparable) ---
sorted scores = [Score(50), Score(75), Score(75), Score(90)]

--- Reference copy (no Copy trait in Java) ---
p1 = Point{x=10, y=20}, p2 = Point{x=10, y=20}
Enter fullscreen mode Exit fullscreen mode

Key differences (Rust vs Java)

Top comments (0)