There is no built-in way. You cannot pass an async closure to the init
in stdlib today. It is pretty trivial to add (based on the stdlib code):
extension Result where Failure == Swift.Error {
public init(catching body: () async throws -> Success) async {
do {
self = .success(try await body())
} catch {
self = .failure(error)
}
}
}
But note that this makes the init
async, so your code would need to be:
let singleSample = await Result { try await UnreliableRandomGenerator().random() }
^^^^^
This would of course have to be called in an async context.
It's possible that what you're trying to do is make a "Future" so you can pass it through synchronous contexts. That already exists. It's called Task
:
let singleSample = Task { try await UnreliableRandomGenerator().random() }
When you want to resolve this into a Result, you can await its .result
property:
let result = await singleSample.result
Or you can skip the Result, and access its value directly with try-value
:
let result = try await singleSample.value
In many cases, Result isn't all that useful in the Structured Concurrency world. It's better to use try
and await
directly. But it can still be very helpful for storing in properties, passing through channels that allow errors, and interacting with non-structured code, so the .result
property on Task is very welcome, and it's nice that it easily can convert to and from throws
.