[swift-users] [swift-evolution] Best way to handle escaping function that might throw
T.J. Usiyan
griotspeak at gmail.com
Tue Jan 10 15:03:38 CST 2017
I suggest using an enum to represent success and failure. It's usually
referred to as `Result`. It might seem weird for the closure that you
presented as an example, since it would be Result<Void>, but it properly
captures the possibility of having thrown.
``` swift
enum UselessError : Swift.Error {
case somethingBadHappened
}
enum Result<T> {
case success(T)
case failure(Swift.Error)
init(throwingClosure: (Void) throws -> T) {
do {
self = try .success(throwingClosure())
} catch {
self = .failure(error)
}
}
}
func burnItDown() throws -> Void {
throw UselessError.somethingBadHappened
}
Result(throwingClosure: burnItDown)
```
On Mon, Jan 9, 2017 at 10:28 PM, Jacob Bandes-Storch via swift-users <
swift-users at swift.org> wrote:
> Moving to swift-users list.
>
> No, there's no way to do this today. The point of rethrows is that within
> one call site, "f(block)" can be treated as throwing if the block throws,
> or not throwing if the block doesn't throw. In your example, once the
> FStore object is constructed, the information about the original passed-in
> function is lost, so the caller has no way to know whether call() can throw
> or not.
>
> If this *were* possible, the information would somehow need to be encoded
> in the type system when creating FStore(f: block). That would require
> something like dependent typing, or generic-param-based-rethrows, e.g.
>
> struct FStore<T: () throws -> Void> { // made-up syntax
> let f: T
> func call() rethrows(T) { try f() } // throws-ness of this function
> depends on throws-ness of T
> }
>
> On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> Hi,
>>
>> If I have an escaping function that I store and then call, I need to
>> declare the calling function as throwing, not rethrowing. EG:
>>
>> struct FStore {
>> let f: () throws -> Void
>> init(f: @escaping () throws -> Void) { self.f = f }
>> func call() throws { try f() } // Can't put rethrows here - have
>> to use throws
>> }
>> Is there a better solution?
>>
>> Thanks for any suggestions,
>>
>> -- Howard.
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170110/6557ed0d/attachment.html>
More information about the swift-users
mailing list