Derive Macros
A derive macro is an attribute written above a type — like #[derive(Debug, Clone, PartialEq)] — that tells the compiler to auto-generate a standard implementation of those traits so you don't write the boilerplate yourself.
Learn Derive Macros in our free Rust course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Rust course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll learn what each common derivable trait generates, when you can and can't derive a trait (for example, why Copy needs all- Copy fields), and how the ordering and hashing traits unlock sorting and hash collections.
What You'll Learn in This Lesson
1️⃣ Debug, Clone, and PartialEq
The three you'll reach for most often: Debug lets you print a value with {' '} (or pretty-print with {' '} ), Clone gives you a .clone() method for an independent copy, and PartialEq enables == and != , comparing field by field.
Each derive wrote real code for you: the {' '} output, the .clone() method, and the == comparison would otherwise be a dozen lines of hand-written impl blocks.
2️⃣ Copy: When You Can and Can't Derive It
Copy changes assignment semantics: a Copy type is duplicated instead of moved , so the original stays usable. The catch: you can only derive Copy if every field is also Copy , and Copy always requires Clone , so they're derived together.
3️⃣ Ordering and Hashing: Eq, Ord, Hash
To sort a type you derive the ordering set PartialEq, Eq, PartialOrd, Ord ; to use it as a key in a HashMap or HashSet you derive Hash (plus Eq ). Derived Ord compares fields in declaration order, so field order is meaningful.
Note Eq and Ord are derivable here only because every field is an integer. If a field were an f64 , you could derive PartialEq / PartialOrd but not Eq / Ord , because NaN breaks total ordering.
Your turn. Fill in the blank marked ___ , then run it.
Derive the right traits so a deck of cards can be sorted and the highest found. Run it with cargo run and check the output.
📋 Quick Reference — Derivable Traits
Practice quiz
What does #[derive(...)] do?
- Renames a type
- Imports a module
- Tells the compiler to auto-generate a standard trait implementation
- Marks code as unsafe
Answer: Tells the compiler to auto-generate a standard trait implementation. It generates a standard impl of a trait for your type so you don't write the boilerplate by hand.
Which derive lets you print a value with {:?}?
- Debug
- Display
- Clone
Answer: Debug. Debug enables {:?} (and pretty {:#?}) formatting.
Which derive enables comparing values with == and !=?
- Ord
- Hash
- Copy
- PartialEq
Answer: PartialEq. PartialEq generates == and !=, comparing field by field.
Why might #[derive(Copy)] fail for a struct with a String field?
- String is too short
- String owns heap data, so it isn't Copy
- Copy needs Debug
- String can't be a field
Answer: String owns heap data, so it isn't Copy. Copy requires every field be Copy; String owns heap data, so the struct can only be Clone.
Copy can only be derived alongside which other trait?
- Clone
- Debug
- Default
- Hash
Answer: Clone. Copy always requires Clone, so they are derived together: #[derive(Clone, Copy)].
Why does f64 implement PartialEq but not Eq?
- f64 is not a number
- Eq is deprecated
- NaN != NaN breaks full equivalence
- f64 has no bits
Answer: NaN != NaN breaks full equivalence. Eq requires every value equal itself, but NaN != NaN, so floats only get PartialEq/PartialOrd.
To use a struct as a key in a HashMap or HashSet, which traits must it derive?
- Debug and Clone
- Hash and Eq
- Ord and Copy
- Display and Default
Answer: Hash and Eq. Hash (plus Eq) lets a type be a hash-collection key.
In what order does derived Ord compare a struct's fields?
- Alphabetically by field name
- Random order
- By field size
- In declaration order, lexicographically
Answer: In declaration order, lexicographically. Derived Ord compares the first declared field, then the second on ties, like sorting words by letters.
Which derive set is needed so a type can be sorted with .sort()?
- Just Debug
- PartialEq, Eq, PartialOrd, Ord
- Clone and Copy
- Hash only
Answer: PartialEq, Eq, PartialOrd, Ord. sort() needs a total order, supplied by deriving the full PartialEq, Eq, PartialOrd, Ord set.
Which derive provides a Type::default() value with zeroed/empty fields?
- Debug
- Clone
- Default
- Ord
Answer: Default. Default generates Type::default(), setting each field to its type's default value.