Skip to content

Commit

Permalink
Fix rust-lang#1060: add page on Impl Trait
Browse files Browse the repository at this point in the history
  • Loading branch information
adamchalmers committed Sep 10, 2019
1 parent 37a2861 commit 6377cb0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
- [Operator Overloading](trait/ops.md)
- [Drop](trait/drop.md)
- [Iterators](trait/iter.md)
- [impl Trait](trait/impl_trait.md)
- [Clone](trait/clone.md)

- [macro_rules!](macros.md)
Expand Down
46 changes: 46 additions & 0 deletions src/trait/impl_trait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# impl Trait

If your function returns a type that implements `MyTrait`, you can write its return type as `-> impl MyTrait`. This can help simplify your type signatures quite a lot!

```rust,editable
use std::iter;
use std::vec::IntoIter;
// This function combines two Vec<i32> and returns an iterator over it.
// Look how complicated its return type is!
fn combine_vecs_explicit_return_type<'a>(
v: Vec<i32>,
u: Vec<i32>,
) -> iter::Cycle<iter::Chain<IntoIter<i32>, IntoIter<i32>>> {
v.into_iter().chain(u.into_iter()).cycle()
}
// This is the exact same function, but its return type uses `impl Trait`.
// Look how much simpler it is!
fn combine_vecs<'a>(
v: Vec<i32>,
u: Vec<i32>,
) -> impl Iterator<Item=i32> {
v.into_iter().chain(u.into_iter()).cycle()
}
```

More importantly, some Rust types can't be written out. For example, every closure has its own unnamed concrete type. Before `impl Trait` syntax, you couldn't write a function like this:

```rust,editable
fn return_closure() -> impl Fn(i32) {
let closure = |x: i32| { println!("the value of x is {}", x) };
closure
}
```

Here's a more realistic example: what if you want to return an iterator that uses `map` or `filter` closures? Because the closure's types don't have names, you can't write out an explicit return type. But with `impl Trait` you can do this easily:

```rust,editable
fn double_positives<'a>(numbers: &'a Vec<i32>) -> impl Iterator<Item = i32> + 'a {
numbers
.iter()
.filter(|x| x > &&0)
.map(|x| x * 2)
}
```

0 comments on commit 6377cb0

Please sign in to comment.