You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In Rust, closures have a unique, un-writable type.
106
+
They do implement the `Fn` family of traits, however.
107
+
This means that previously, the only way to return a closure from a function was to use a trait object:
108
+
109
+
```rust
110
+
fnreturns_closure() ->Box<dynFn(i32) ->i32> {
111
+
Box::new(|x|x+1)
112
+
}
113
+
```
114
+
115
+
You couldn't write the type of the closure, only use the `Fn` trait.
116
+
That means that the trait object is necessary. However, with `impl Trait`:
117
+
118
+
```rust
119
+
fnreturns_closure() ->implFn(i32) ->i32 {
120
+
|x|x+1
121
+
}
122
+
```
123
+
124
+
We can now return closures by value, just like any other type!
125
+
126
+
## More details
127
+
128
+
The above is all you need to know to get going with `impl Trait`, but for some more nitty-gritty details: type parameters and `impl Trait` work slightly differently when they're in argument position versus return position.
129
+
Consider this function:
130
+
131
+
```rust,ignore
132
+
fn foo<T: Trait>(x: T) {
133
+
```
134
+
135
+
When you call it, you set the type, `T`.
136
+
"you" being the caller here.
137
+
This signature says "I accept any type that implements `Trait`."
138
+
("any type" == universal in the jargon)
139
+
140
+
This version:
141
+
142
+
```rust,ignore
143
+
fn foo<T: Trait>() -> T {
144
+
```
145
+
146
+
is similar, but also different.
147
+
You, the caller, provide the type you want, `T`, and then the function returns it.
148
+
You can see this in Rust today with things like parse or collect:
149
+
150
+
```rust,ignore
151
+
let x: i32 = "5".parse()?;
152
+
let x: u64 = "5".parse()?;
153
+
```
154
+
155
+
Here, `.parse` has this signature:
156
+
157
+
```rust,ignore
158
+
pub fn parse<F>(&self) -> Result<F, <F as FromStr>::Err> where
159
+
F: FromStr,
160
+
```
161
+
162
+
Same general idea, though with a result type and `FromStr` has an associated type... anyway, you can see how `F` is in the return position here.
163
+
So you have the ability to choose.
164
+
165
+
With `impl Trait`, you're saying "hey, some type exists that implements this trait, but I'm not gonna tell you what it is."
166
+
So now, the caller can't choose, and the function itself gets to choose.
167
+
If we tried to define parse with `Result<impl F,...` as the return type, it wouldn't work.
168
+
169
+
### Using `impl Trait` in more places
170
+
171
+
As previously mentioned, as a start, you will only be able to use `impl Trait` as the argument or return type of a free or inherent function.
172
+
However, `impl Trait` can't be used inside implementations of traits, nor can it be used as the type of a let binding or inside a type alias.
173
+
Some of these restrictions will eventually be lifted.
174
+
For more information, see the [tracking issue on `impl Trait`](https://github.com/rust-lang/rust/issues/34511).
0 commit comments