---
title: "16.1 Introduction to traits"
description: "A trait defines shared behavior that many types can implement; defining a trait, implementing it for a type, and why traits are the structural center of Rust."
url: "https://learnrust.net/chapter-16/introduction-to-traits/"
last_updated: "2026-06-13"
---

# 16.1 Introduction to traits

This is the chapter the last one pointed at, and arguably the structural center of the whole language. A **trait** defines shared behavior, a set of methods, that many different types can implement. If structs and enums (chapters 10 and 11) are how you describe *data*, traits are how you describe what data can *do*, in a way that cuts across types. They're also the answer to the cliffhanger from chapter 15: traits are what let a generic function say "`T` is any type that can be compared," and the `largest` function finally compiles in lesson [16.3](https://learnrust.net/chapter-16/trait-bounds/).

## Shared behavior across different types

Suppose you have two types, a `Tweet` and an `Article`, and you want both to be able to produce a short summary. The summary logic differs (a tweet shows its author, an article its headline), but the *capability*, "can be summarized", is shared. A trait captures that shared capability:

```rust
trait Summary {
    fn summarize(&self) -> String;
}
```

Read this as: "`Summary` is a behavior; any type that has it must provide a `summarize` method taking `&self` and returning a `String`." The trait declares the method's *signature* (lesson [13.8](https://learnrust.net/chapter-13/reading-documentation/): a signature is a contract) but no body, ending in a semicolon. It's a promise of what implementing types will provide, not the provision itself. This is the same idea as the `Debug` and `Default` you've been deriving since lesson [10.7](https://learnrust.net/chapter-10/deriving-debug/): those are traits too, and now you'll see what's underneath them.

## Implementing a trait for a type

A type *implements* a trait by providing the methods the trait requires, in an `impl Trait for Type` block:

```rust
struct Tweet {
    username: String,
    content: String,
}

struct Article {
    headline: String,
    author: String,
}

impl Summary for Tweet {
    fn summarize(&self) -> String {
        format!("@{}: {}", self.username, self.content)
    }
}

impl Summary for Article {
    fn summarize(&self) -> String {
        format!("{} by {}", self.headline, self.author)
    }
}

fn main() {
    let tweet = Tweet {
        username: String::from("rustlang"),
        content: String::from("traits are great"),
    };
    let article = Article {
        headline: String::from("Rust 2.0 Released"),
        author: String::from("the team"),
    };

    println!("{}", tweet.summarize());
    println!("{}", article.summarize());
}
```

```
@rustlang: traits are great
Rust 2.0 Released by the team
```

`impl Summary for Tweet` reads "implement the `Summary` behavior for `Tweet`," and inside it you write the `summarize` body that's right for a tweet. The `Article` implementation does the same with its own logic. Now both types *have* the `Summary` behavior, and both expose a `summarize()` method, even though they're unrelated types with different fields. This is the difference from the plain `impl` blocks of chapter 10: `impl Tweet` adds methods that belong to `Tweet` alone, while `impl Summary for Tweet` declares that `Tweet` participates in a shared behavior that other types share too.

> **Key insight**
>
> A trait separates *what* a type can do from *how* it does it. The `Summary` trait says "summarizable things have a `summarize` method"; each type fills in its own how. This is the foundation for writing code that works with "any summarizable type" without caring which one, the trait-bound generics of lesson [16.3](https://learnrust.net/chapter-16/trait-bounds/). Traits are how Rust achieves the flexibility that other languages get from inheritance, but built from composition instead (lesson [16.10](https://learnrust.net/chapter-16/code-reuse-without-inheritance/)).

## The coherence rule

One rule, stated now because it shapes everything: you can implement a trait for a type only if *you* define either the trait or the type (or both). You can implement your own `Summary` trait for the standard library's `String` (you own the trait), and you can implement the standard library's `Display` trait for your own `Tweet` (you own the type). But you cannot implement someone else's trait for someone else's type, say `Display` for `Vec`, because both belong to other code. This is the **orphan rule** (part of *coherence*), and it exists so that two unrelated libraries can't each define conflicting implementations that break when used together. You'll rarely bump into it, and when you do, the newtype pattern (lesson [10.4](https://learnrust.net/chapter-10/tuple-structs-and-unit-structs/)) is the standard workaround: wrap the foreign type in your own.

## What this chapter replaces

It's worth pausing on scale. Traits do the job that C++ spreads across operator overloading, inheritance, virtual functions, abstract base classes, and template specialization, many chapters of material in a course like learncpp. Rust folds all of it into one feature: a trait, and types that implement it. Over the next ten lessons you'll see traits handle shared behavior (this lesson), default methods, generic bounds, operator overloading (lesson [16.7](https://learnrust.net/chapter-16/operator-overloading/)), conversions (lesson [16.8](https://learnrust.net/chapter-16/from-and-into/)), and polymorphism (lesson [16.9](https://learnrust.net/chapter-16/trait-objects/)), each a thing that needed its own large feature elsewhere. This is the chapter where "the Rust course is shorter" is most dramatically earned.

## Quiz time

**Question #1**

What does a trait define, and what does a type do to "have" that trait?

<details class="solution">
<summary>Show solution</summary>

A trait defines shared behavior: a set of method signatures (a contract) that implementing types must provide. A type *implements* the trait by writing an `impl Trait for Type` block supplying those methods with bodies appropriate to that type. After that, the type has the trait's behavior.

</details>

**Question #2**

What's the difference between `impl Tweet { ... }` and `impl Summary for Tweet { ... }`?

<details class="solution">
<summary>Show solution</summary>

`impl Tweet` (chapter 10) adds inherent methods that belong to `Tweet` alone. `impl Summary for Tweet` declares that `Tweet` implements the shared `Summary` trait, providing the methods that trait requires, behavior that other types can also implement. The first is type-specific; the second participates in a cross-type contract.

</details>

**Question #3**

Can you implement the standard library's `Display` trait for the standard library's `Vec` type? Why or why not?

<details class="solution">
<summary>Show solution</summary>

No. The orphan rule (coherence) requires that you own either the trait or the type. Both `Display` and `Vec` belong to the standard library, so you can implement neither for the other. You *could* implement `Display` for your own type, or your own trait for `Vec`. The workaround for a foreign-trait-on-foreign-type case is to wrap `Vec` in a newtype you own (lesson [10.4](https://learnrust.net/chapter-10/tuple-structs-and-unit-structs/)).

</details>

A trait can require a method, as `Summary` does. It can also *provide* one, a default implementation that types get for free unless they override it. That's the next lesson, and it's the first hint of how traits reduce code.

## Sitemap

See the full [sitemap](https://learnrust.net/sitemap.md) for all pages.
