Coding/Learn/rust/traits and generics
Rust Foundational Course
01.Introduction to Rust & Memory Safety
02.Formatting, Comments & Macros (println!)
03.Variables, Mutability & Shadowing
04.Scalar & Compound Types (Integers, Floats, Tuples, Arrays)
05.Functions, Parameters & Return Expressions
06.Conditionals & If as an Expression
07.Ownership Rules & Move Semantics
08.References & Borrowing (&T)
09.Mutable References (&mut) & Aliasing XOR Mutability
10.Slices & String Types (&str vs String)
11.Loops in Rust (loop, while, for)
12.Pattern Matching with match Expressions
13.Structs, Associated Functions & Methods (impl)
14.Enums & the Option<T> Type (No Null!)
15.Concise Pattern Matching (if let & let else)
16.Vectors & Growable Collections (Vec<T>)
17.Error Handling with Result<T, E> & the ? Operator
18.Traits, Shared Behavior & Generics
19.Closures & Functional Iterators (map, filter, collect)
20.Capstone: High-Performance In-Memory Log Telemetry Engine
Course Certificate0%

Complete all lessons to earn

LearnTraits, Shared Behavior & Generics
18 / 20 0%
Lesson 18 of 20
7 mins read

Traits, Shared Behavior & Generics

PreviousNext Lesson
In Plain English

Traits define shared behavior across distinct types (similar to interfaces in other languages). Generics allow writing reusable functions and data structures with trait bounds (e.g. T: Summary) enforced at compile time with zero runtime dispatch cost (monomorphization).

The Mental Model

"A trait is like a universal electrical outlet standard: any device that implements the Plug trait (phone charger, kettle, laptop) can draw power from the wall without the wall needing to know the specific brand of device."

Deep Dive: How It Works

Trait Definition: pub trait Describable { fn describe(&self) -> String; }

Implementing Traits: impl Describable for User { fn describe(&self) -> String { ... } }

Monomorphization: The compiler generates specialized machine code for each concrete type used with generics, resulting in raw native speed.

Syntax Blueprint

fn print_summary<T: Describable>(item: &T) { println!("{}", item.describe()); }

Trait bounds constrain generic type parameters to types that implement required behavior.

PointCore Rules to Remember

Point star
Shared Interfaces: Traits specify method contracts that types must fulfill.
Point star
Zero Runtime Overhead: Static dispatch via monomorphization runs as fast as hand-specialized functions.
Point star
Default Implementations: Traits can provide fallback method bodies that types can override.

Common Beginner Traps & How to Fix Them

Mistake:Trying to call a trait method without importing the trait into scope.

Why it happens: Trait methods are only visible when the trait itself is in scope.

How to fix: Add use path::to::Trait; at the top of the file.

Pro Tip: Use where clauses for clean trait bounds on complex signatures: fn process<T, U>(a: T, b: U) where T: Clone, U: Debug.

Live Interactive Example

Hit Run Code to see it live
Trait Definition and Generic Dispatch
Rust 1.78 / rustc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Output Console
Click "Run Code" to view the rendered output.
How it works: The generic function display_entity accepts any type implementing Formattable.

Your Turn: Micro Challenge

No pressure! Edit the starter code below and test your solution with instant feedback.

Micro Exercise

Implement Printable trait on a struct

  • PointDefine trait Printable { fn print_info(&self); }
  • PointCreate struct Device { name: String }; and implement Printable for Device to print "Device: {name}".
  • PointIn main(), let d = Device { name: String::from("ZenChip") }; d.print_info();
1
2
3
4
5
6
7
Sandbox Output
Click "Run & Check" to test your solution.

Finished reading and practicing?

Mark this lesson as completed to update your course progress.

PreviousNext Lesson
Overview100 SheetLearnCertificates