impl Trait
- Rust course
- Intermediate
- Lesson 22/115
- 4 min
Specify parameter and return types with impl Trait.
impl Trait
In return position, impl Trait means "I return a single concrete type implementing this trait, but I won't name it". It's used to return types whose names are very long or unwritable, like iterators and closures:
fn ciftler(n: u32) -> impl Iterator<Item = u32> {
(0..n).filter(|x| x % 2 == 0)
}
fn carpan(k: i32) -> impl Fn(i32) -> i32 {
move |x| x * k
}The real type of ciftler is Filter<Range<u32>, {closure}>; closure types can't be named at all.
What does the caller see?
The caller can only use what the trait offers; this gives the freedom to change internal details:
let v: Vec<u32> = ciftler(10).collect(); // [0, 2, 4, 6, 8]
let uc_kat = carpan(3);
println!("{}", uc_kat(7)); // 21move makes the closure take ownership of k by copying it; it's needed because k is gone once the function ends.
Practice Hidden return types
Write the ciftler and carpan functions above. Collect ciftler(10) into a vector and multiply 7 with carpan(3); print both separated by a space.
Starter code
fn main() {
// buraya yaz
}Sample solution
fn ciftler(n: u32) -> impl Iterator<Item = u32> {
(0..n).filter(|x| x % 2 == 0)
}
fn carpan(k: i32) -> impl Fn(i32) -> i32 {
move |x| x * k
}
fn main() {
let v: Vec<u32> = ciftler(10).collect();
let uc_kat = carpan(3);
println!("{:?} {}", v, uc_kat(7));
}Expected output
[0, 2, 4, 6, 8] 21
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Why doesn't <code>fn f(b: bool) -> impl Display { if b { 5 } else { "beş" } }</code> compile?
- if isn't an expression
- It compiles
- impl Trait must be a single concrete type; i32 and &str differ Correct answer
- Display can't be returned
Explanation: Returning different types needs dynamic dispatch, like Box<dyn Display>.
2 Return an iterator
fn ciftler(n: u32) -> ____ {
(0..n).filter(|x| x % 2 == 0)
}
fn ciftler(n: u32) -> impl Iterator<Item = u32> {
(0..n).filter(|x| x % 2 == 0)
}
Explanation: impl Iterator<Item = u32> returns an unnamed iterator producing u32.
3 Return type and meaning
| Term | Meaning |
|---|---|
-> impl Iterator<Item = u32> |
Hidden iterator |
-> impl Fn(i32) -> i32 |
Hidden closure |
-> Box<dyn Display> |
Can be different types |
-> Vec<u32> |
Concrete, owned |