After my naive attempt at defining an array of async let bindings
:
let fv: [() async -> Int] = [f, g, h]
let uv: [async Int] = [] // <--- not possible
for f in fv {
async let u = f ()
uv.append (u)
}
for u in uv {
await print (u)
}
I asked the question "Will array of async values be possible?" here .
The answer was not a definite no.
However, @crontab has a utility (Zip) in his personal library, which provides a good workable solution.
It uses a task group underneath, which simplifies the nesting of the task groups, resulting in clean looking code.
@main
enum AsyncZip {
static func main () async throws {
@Sendable func n () -> Int {
let v = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
return v [Int.random (in: 0..<v.count)]
}
@Sendable func f () async throws -> Int {n () + 1}
let u = Zip (actions: [f, f, f])
try await print (u.result)
@Sendable func p () async throws -> [Int] {
let u = Zip (actions: [f, f, f, f, f])
return try await u.result
}
var v = Zip <[Int]> ()
v.add (p)
v.add (p)
v.add (p)
try await print (v.result)
}
}
Possible output:
[18, 30, 30]
[[3, 32, 38, 24, 8], [8, 3, 30, 12, 8], [38, 6, 24, 3, 38]]