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
  • Print

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.