4 ms·
Ah that's true, but I think it ends up hairier when you combine the two together and have closures that are async, e.g.: let x = || -> i32 { 1 }; // fine
by vore 3y ago
Ah that's true, but I think it ends up hairier when you combine the two together and have closures that are async, e.g.:
let x = || -> i32 { 1 }; // fine
let x = || -> impl Future<Output = i32> { async { 1 } }; // error: `impl Trait` only allowed in function and inherent method return types, not in closure return types
Unless I'm missing something, sometimes you do have to name the return type of an async closure if it's returning e.g Result<T, Box<dyn Error>>, and use of the ? operator means that the return type can't be inferred without an explicit annotation.
- saghm 3y agoI think part of the disconnect is that that what you're calling an "async closure" is more directly an analog of a "regular" function that happens to return a future rather than an "async fn" declared function; you'd need similar syntactic boilerplate for annotating a function that's not declared as "async". Currently, there is no closure version of an "async fn" in Rust, but it's arguably not particularly necessary because you can use a Future as the async version of a closure in a lot of cases due to them being lazy already. For example, spawning a task with tokio just takes a Future, not a closure like spawning a sync thread.
- veber-alex 3y agoYou can annotate the return type inside the closure in those cases, for example: let x = || async { let file = std::fs::read_to_string("foo.txt")?; Ok::<_, Box<dyn std::error::Error>>(file) };