This particular example does not demonstrate any features of the unboxed_closures
feature other than that it enables the ability to explicitly name the Fn
traits by syntax sugar free interface. I.e. writing Fn<(A,B), Output = C>
instead of Fn(A, B) -> C
. The ability to nest impl
like this is readily available on stable and can be used with other traits like e.g. Iterator
fn print_all(it: impl IntoIterator<Item = impl AsRef<[u8]>>) {
println!("--------------------");
for slice in it {
println!("{:?}", slice.as_ref());
}
}
fn main() {
let x = vec!["hello".to_string(), "world".to_string()];
let y = [[1u8, 2, 3], [4, 5, 6]];
print_all(x);
print_all(&y);
}
(playground)
It is “only” the fact that impl Trait
syntax is not allowed in the return type of a Fn
trait that makes this not work. But this is to be expected since those traits are not stabilized yet. As a matter of fact, it might (and in my personal opinion should) be considered to change the closure output type from an associated type into a type parameter, and impl Trait
is currently not supported to occur nested in type parameters of another impl Trait
, like e.g. x: impl PartialEq<impl Debug>>
.
Finally, this function
fn solve(a: Vec<f64>, mul: impl FnOnce<(i32,), Output = impl MatVecMul>) -> f64 {
todo!()
}
is exactly the same as this one
fn solve<R: MatVecMul>(a: Vec<f64>, mul: impl FnOnce(i32) -> R) -> f64 {
todo!()
}
or this one
fn solve<R: MatVecMul, F: FnOnce(i32) -> R>(a: Vec<f64>, mul: F) -> f64 {
todo!()
}
except for the fact that the latter two variants compile successfully on stable and the last one supports explicit passing of the generic type arguments R
and F
.