The Default & Clone Traits
The Default trait supplies a standard starting value for a type via Default::default() , while the Clone trait provides an explicit .clone() method that makes an independent copy, including deep-copying heap data.
Learn The Default & Clone Traits in our free Rust course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
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 derive and hand-write Default , use the ..Default::default() struct update syntax, and learn exactly how Clone differs from Copy .
What You'll Learn in This Lesson
1️⃣ Deriving Default
Add #[derive(Default)] and the compiler writes a default() that sets every field to its own type's default: 0 for numbers, false for bool , an empty String , an empty Vec , and so on. Build the value with Type::default() or Default::default() .
Both forms produce the same value. Use Type::default() when you want to be explicit, and the bare Default::default() when the target type is already known from context.
2️⃣ Custom Defaults and the Update Syntax
When zero isn't the right starting value, implement Default by hand — it's just returning your chosen values. Then the ..Default::default() struct update syntax lets you set a few fields explicitly and fill the rest from the default.
3️⃣ Clone vs Copy
Copy is implicit and cheap: assignment duplicates the value bit for bit and the original stays valid, but it's only allowed when every field is Copy . Clone is explicit: you call .clone() , and it can do real work like deep-copying a heap String . Any type with a String or Vec field can be Clone but not Copy .
PointCopy duplicates silently on let q = p; . Person owns a heap String , so it needs an explicit .clone() to make an independent copy. Every Copy type must also implement Clone .
Your turn. Fill in the blank marked ___ , then run it.
Hand-write Default for a game state, then clone it and mutate the copy. Run it with cargo run and check the output.
📋 Quick Reference — Default & Clone
Practice quiz
What single method does the Default trait provide?
- new()
- init()
- default()
- empty()
Answer: default(). Default provides default(), which returns a sensible starting value for the type.
With #[derive(Default)], what value does a numeric field get?
- 0
- 1
- -1
- Its maximum
Answer: 0. Derived Default gives each field its type's default: 0 for numbers, false for bool, empty String/Vec.
What does #[derive(Default)] give a bool field and a String field?
- true and a space
- false and null
- 1 and "0"
- false and an empty String
Answer: false and an empty String. A bool defaults to false and a String defaults to an empty String.
What does ..Default::default() do in a struct literal?
- Resets all fields to zero
- Fills the fields you didn't set from the default
- Calls a constructor
- Overrides every field
Answer: Fills the fields you didn't set from the default. It fills every remaining (unset) field from the type's Default implementation.
Where must ..Default::default() appear in a struct literal?
- Last
- First
- Anywhere
- Only alone
Answer: Last. The .. spread must come last; it only fills the fields you didn't already set.
When should you implement Default by hand instead of deriving it?
- Never
- Only for enums
- When a field needs a non-zero default like volume 50
- When the struct has one field
Answer: When a field needs a non-zero default like volume 50. Hand-write Default when zero/empty isn't right, e.g. a volume that should start at 50 or a port at 8080.
What is the real difference between Copy and Clone?
- They are identical
- Copy is implicit and bitwise; Clone is explicit via .clone() and can deep-copy
- Clone is implicit; Copy is explicit
- Copy works only on strings
Answer: Copy is implicit and bitwise; Clone is explicit via .clone() and can deep-copy. Copy duplicates implicitly with a bitwise copy; Clone is an explicit .clone() that can deep-copy heap data.
Why can a struct with a String field be Clone but not Copy?
- String is not a type
- Copy is deprecated
- Clone forbids strings
- String owns heap data, which isn't trivially bitwise-copyable
Answer: String owns heap data, which isn't trivially bitwise-copyable. Copy requires all fields be Copy; String owns heap memory, so the struct can only be Clone.
After let q = p; where p is a Copy type, is p still valid?
- No, it was moved
- Yes, Copy types duplicate so the original stays valid
- Only if you call .clone()
- Only inside a loop
Answer: Yes, Copy types duplicate so the original stays valid. Copy duplicates the value on assignment, so the original p remains usable.
Which relationship between Copy and Clone always holds?
- Clone requires Copy
- They are mutually exclusive
- Every Copy type must also implement Clone
- Neither requires the other
Answer: Every Copy type must also implement Clone. Every Copy type must also implement Clone, so they are derived together: #[derive(Clone, Copy)].