🎓 A1Learner
🔍
0 of 149 lessons completed

Rust Returning impl Trait

Returning impl Trait means a function returns a value of a hidden type that implements a trait. The caller can use the trait methods, and nothing more.

Promise the trait, hide the type

Write -> impl Trait after the arrow to return some type that implements the trait, without naming the exact type:

fn featured() -> impl Summary {
    Article { title: String::from("Rust in practice") }
}

The caller uses trait methods only

The caller knows the trait, not the concrete type — so only trait methods are available:

let item = featured();
println!("{}", item.summarize());

Made for iterators and closures

This is ideal for closures and iterators, whose real type names are long or cannot be written at all. A chained iterator is the classic case:

fn doubled() -> impl Iterator<Item = i32> {
    vec![1, 2, 3].into_iter().map(|n| n * 2)
}
println!("{:?}", doubled().collect::<Vec<i32>>());

One function, one concrete type

Only one concrete type may be returned. Returning two different types in different branches does not compile — the error is E0308, mismatched types:

fn pick(coin: bool) -> impl Summary {
    if coin {
        Article { title: String::from("A") }
    } else {
        Post { title: String::from("P") }
    }
}

A returned iterator may borrow

Tie the returned iterator's life to the input it reads with + 'a:

fn positives<'a>(nums: &'a [i32]) -> impl Iterator<Item = i32> + 'a {
    nums.iter().copied().filter(|n| *n > 0)
}
let nums = vec![-2, 3, -1, 5];
println!("{:?}", positives(&nums).collect::<Vec<i32>>());

Example

trait Summary { fn summarize(&self) -> String; }
struct Article { title: String }
impl Summary for Article {
    fn summarize(&self) -> String { format!("Read more: {}", self.title) }
}
fn featured() -> impl Summary {
    Article { title: String::from("Rust in practice") }
}
fn main() {
    let item = featured();
    println!("{}", item.summarize());
}

Key points

  • Use it to hide an internal choice: you may swap the concrete type later without changing callers
  • That is the trait-object tool from the Trait Bounds lesson.
  • A function returning impl Trait hides the concrete type behind the trait it names.

In this example, featured promises only impl Summary. Inside, it builds an Article with the title Rust in practice. main receives the value without ever naming Article, and calls summarize on it — a trait method, so it is allowed. The method builds Read more: Rust in practice, and that is what prints.

Note

For a choice between different return types at run time, use Box<dyn Trait> instead.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

Can a function returning impl Summary return an Article in one branch and a Post in another?