Reputation: 941
I have a problem with some Swift 2 code, compiled using Xcode 7 beta 3.
I have a class (see below) that has an initializer that takes a function, f, which can throw. If f does not throw, then a member variable (self.result) should be set to an instance of an enum that wraps the value that f returns. If f does throw, then self.result should be set to an instance of the enum that indicates the value is absent. At the end of the initializer, self.result should not be nil. I have checked the case where the f does not throw, and the behavior is correct. However, in the case that f does throw, self.result is nil at the end of the initializer (the assert is triggered). If I single-step in the debugger, I see that self.result seems to instantaneously be set and then flashes back to being nil.
(Note: You might suggest I represent the absence of a result as nil, rather than wrapping in the enum. However, I need to model the scenario in which the result of f has not been computed yet, has been computed successfully, or an attemopt has been made to compute the result but it has failed. Hence the enum.)
Have I misunderstood how Swift 2's error handling works? Or, is the compiler/debugger etc. behaving incorrectly?
Thanks in advance.
internal enum Result<T> {
case Value(T)
case None
}
public final class MyClass<T> {
internal var result: Result<T>? = nil
private init(f: () throws -> T) {
let queueName = “some.string”
let queue = dispatch_queue_create(queueName, DISPATCH_QUEUE_CONCURRENT)
dispatch_async(queue) {
do {
let value = try f()
self.result = .Value(value)
}
catch {
self.result = .None
}
assert(self.result != nil, "Result must have value before block returns.")
}
}
}
Upvotes: 2
Views: 99
Reputation: 539815
In
self.result = .None
the left-hand side is an optional Result
, therefore .None
on
the right-hand side is inferred as Optional.None
, and the statement
is equivalent to
self.result = nil
What you probably meant is
self.result = Result.None
and then the assertion does not fail anymore. Alternatively,
use a different enumeration value, e.g. case NoValue
in your custom
type.
Upvotes: 5