2023-11-29 10:39:24 -05:00
|
|
|
---
|
|
|
|
minutes: 5
|
|
|
|
---
|
|
|
|
|
2022-12-21 16:36:30 +01:00
|
|
|
# `impl Trait`
|
|
|
|
|
|
|
|
Similar to trait bounds, an `impl Trait` syntax can be used in function
|
|
|
|
arguments and return values:
|
|
|
|
|
|
|
|
```rust,editable
|
2023-11-29 10:39:24 -05:00
|
|
|
// Syntactic sugar for:
|
|
|
|
// fn add_42_millions<T: Into<i32>>(x: T) -> i32 {
|
|
|
|
fn add_42_millions(x: impl Into<i32>) -> i32 {
|
|
|
|
x.into() + 42_000_000
|
|
|
|
}
|
2022-12-21 16:36:30 +01:00
|
|
|
|
2023-11-29 10:39:24 -05:00
|
|
|
fn pair_of(x: u32) -> impl std::fmt::Debug {
|
|
|
|
(x + 1, x - 1)
|
2022-12-21 16:36:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
2023-11-29 10:39:24 -05:00
|
|
|
let many = add_42_millions(42_i8);
|
|
|
|
println!("{many}");
|
|
|
|
let many_more = add_42_millions(10_000_000);
|
|
|
|
println!("{many_more}");
|
|
|
|
let debuggable = pair_of(27);
|
|
|
|
println!("debuggable: {debuggable:?}");
|
2022-12-21 16:36:30 +01:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2023-01-16 14:15:00 +00:00
|
|
|
<details>
|
|
|
|
|
2023-11-29 10:39:24 -05:00
|
|
|
`impl Trait` allows you to work with types which you cannot name.
|
2023-01-16 14:15:00 +00:00
|
|
|
The meaning of `impl Trait` is a bit different in the different positions.
|
|
|
|
|
|
|
|
* For a parameter, `impl Trait` is like an anonymous generic parameter with a trait bound.
|
2023-03-28 15:42:56 -04:00
|
|
|
|
2023-01-16 14:15:00 +00:00
|
|
|
* For a return type, it means that the return type is some concrete type that implements the trait,
|
|
|
|
without naming the type. This can be useful when you don't want to expose the concrete type in a
|
|
|
|
public API.
|
|
|
|
|
2023-03-28 15:42:56 -04:00
|
|
|
Inference is hard in return position. A function returning `impl Foo` picks
|
|
|
|
the concrete type it returns, without writing it out in the source. A function
|
|
|
|
returning a generic type like `collect<B>() -> B` can return any type
|
|
|
|
satisfying `B`, and the caller may need to choose one, such as with `let x:
|
|
|
|
Vec<_> = foo.collect()` or with the turbofish, `foo.collect::<Vec<_>>()`.
|
|
|
|
|
2023-11-29 10:39:24 -05:00
|
|
|
What is the type of `debuggable`? Try `let debuggable: () = ..` to see what the
|
|
|
|
error message shows.
|
2023-03-28 15:42:56 -04:00
|
|
|
|
2023-01-16 14:15:00 +00:00
|
|
|
</details>
|