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)].