'Unable to return a Vec<Box<dyn Fn(f32) -> f32>>
I am trying to return a vector of closures from a function in Rust. Each of which will ultimately be stored on a struct which holds a Box<dyn Fn(f32) -> f32>. Here is a simple reproduction of the error:
fn something() -> Vec<Box<dyn Fn(f32) -> f32>> {
let mut vec = Vec::new();
for i in 0..5 {
vec.push(
Box::new(
|t : f32| { t + 1.0 }
)
);
}
vec
}
error[E0308]: mismatched types
--> src\main.rs:13:5
|
2 | fn something() -> Vec<Box<dyn Fn(f32) -> f32>> {
| ---------------------------- expected `Vec<Box<(dyn Fn(f32) -> f32 + 'static)>>` because of return
type
...
8 | |t : f32| { t + 1.0 }
| --------------------- the found closure
...
13 | vec
| ^^^ expected trait object `dyn Fn`, found closure
|
= note: expected struct `Vec<Box<(dyn Fn(f32) -> f32 + 'static)>>`
found struct `Vec<Box<[closure@src\main.rs:8:17: 8:38]>>`
I don't understand this error and where it is coming from, given that the provided closure implements the required trait. I am new to Rust and struggling the most with closures.
Solution 1:[1]
This happens because the concrete type of the closure you specified takes precedence over the return type when inferring the type of the Vec. In other words, since the closure itself, |t : f32| { t + 1.0 } has an anonymous yet concrete type, it is inferred to be the type of the Vec.
This can be fixed by explicitly ascribing the type:
let mut vec: Vec<Box<dyn Fn(f32) -> f32>> = Vec::new();
Or, by telling the compiler that we still don't know the type, letting it then infer from the return type:
vec.push(
Box::new(
|t : f32| { t + 1.0 }
) as Box<_>
);
Notice the added as Box<_>.
As a general rule of thumb, Rust is probably able to infer the type correctly, just that its inference rules sometimes tell it to stick to the earliest concrete type. When you hit a snag such as this one, just try tacking on as Box<_> or otherwise (such as as _, or as Arc<_>, etc.).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Optimistic Peach |
