Course contentsShow
← Rust
Lesson 48 of 1,9101. Rust Fundamentals and ToolingFree lesson

Trait-Based Interfaces

Define shared behavior contracts that different types can implement for polymorphism.

In this lesson, you will learn how to define shared behavior contracts that allow different types to be used interchangeably in your programs.

The Concept of Shared Behavior

Imagine you are building a game with different types of characters: Wizard, Warrior, and Archer. While these are very different structures, they all need to be able to "attack." In Rust, a Trait is a way to define a set of methods that a type must provide to fulfill a specific role.

Think of a trait as a job description. It doesn't tell you how to do the job, only that the job must be done. Any type that implements that trait is guaranteed to have those methods available.

Defining and Implementing

First, you define the trait using the trait keyword. This acts as the blueprint:

trait Attacker {
    fn attack(&self);
}

Next, you create your structs and implement the trait for them. The implementation provides the specific logic for each type:

struct Wizard;
struct Warrior;

impl Attacker for Wizard {
    fn attack(&self) {
        println!("Casting fireball!");
    }
}

impl Attacker for Warrior {
    fn attack(&self) {
        println!("Swinging sword!");
    }
}

Why This Matters: Polymorphism

The power of traits is that you can write code that doesn't care exactly what a type is, as long as it implements the required trait. This is known as polymorphism. Because both Wizard and Warrior implement Attacker, you can treat them as "things that can attack."

If you write a function that accepts &impl Attacker, Rust allows you to pass in any type that has implemented that trait. This makes your code highly modular; if you want to add a Dragon later, you just implement Attacker for it, and your existing game logic will work with the Dragon without needing any modifications.

Traits define the "what" rather than the "how," allowing different data structures to communicate through a unified interface.

Key Takeaway: Traits allow you to define shared capabilities that enable disparate types to be used interchangeably, making your code flexible and extensible.