let asyncClosure1: @MainActor () async -> Void
let ayncClosure2: @MainActor () -> Void
are these two function signatures different?
let asyncClosure1: @MainActor () async -> Void
let ayncClosure2: @MainActor () -> Void
are these two function signatures different?
Yes, they have different types:
// assuming `var` instead `let`…
asyncClosure1 = asyncClosure2
// ok
asyncClosure2 = asyncClosure1
// error: Invalid conversion from 'async' function of
// type '@MainActor () async -> Void' to synchronous
// function type '@MainActor () -> Void'
They're indistinguishable at the call site, but asyncClosure1
can itself suspend, while asyncClosure2
cannot.
Is there any practical difference? Well…
You can't write any async
calls in the body of a non-async closure, so asyncClosure2
is more limited on what closures it can store.
If called from a @MainActor
context, asyncClosure1
requires an await
, but asyncClosure2
doesn't. The await
can be an issue due to actor reentrancy.