Reputation: 48436
Apple's Swift language documentation says that optional binding (a.k.a. if let
) will "check for a value inside an optional" and "extract that value into" a variable or constant). But this doesn't match what I'm seeing. For example
var x: Int? = nil
if let y1: Int? = x {
println("y1 = \(y1)") // This is printed, suggesting that x is not checked "inside", but left as Optional(nil) (!= nil)
}
if let y2: Int? = x? {
println("y2 = \(y2)")
}
if let y3: Int = x? {
println("y3 = \(y3)")
}
if let y4: Int = x {
println("y4 = \(y4)")
}
if let y5 = x? {
println("y5 = \(y5)")
}
if let y6 = x {
println("y6 = \(y6)")
}
results in (only)
"y1 = nil"
suggesting that no checking "inside" of x
is taking place in the y1
case (and that x
is left as a wrapped nil
, which is not equal to unwrapped nil
). The y2
case seems to confirm this by forcing a "check inside" (or is that just optional chaining "taking over"); but there must be more to the story since the y4
and y6
cases also do not print and thus behave as if a "check inside" is happening.
I suspect that there's some insight to be gained from trying
"x = 42"
which results in
"y1 = Optional(42)"
"y2 = Optional(42)"
"y3 = 42"
"y4 = 42"
"y5 = 42"
"y6 = 42"
but if three's some there, it's lost on me.
It seems like (1) the "optional" on the right side of the expression does indeed get "checked inside" if an explicit check is asked for (with ?
); but otherwise (2) the left hand side of the expression influences how far "inside" a check is performed (just far enough to make a valid assignment).
How is optional binding working in each of these cases? In particular, when x == nil
why does y1
print, and given that it does, why don't y4
and y6
(or generate assignment errors)?
Upvotes: 2
Views: 418
Reputation: 52530
You assigned an optional Int to an optional Int. The assignment did succeed. It will always succeed, whether the optional Int contained an Int or not.
Upvotes: 1
Reputation: 19514
I interpret this differently:
var x: Int? = 1
if let y1: Int = x {
println("y1 = \(y1)")
}
//prints y = 1, the optional was checked, contains a value and passes it
var x: Int? = nil
if let y1: Int = x {
println("y1 = \(y1)")
}
//does not execute because x does not contain value that can be passed to a non optional y
var x: Int? = nil
if let y1: Int? = x {
println("y1 = \(y1)")
}
// y = nil, since y is optional and can hold a value of x which is nil, then it passes nil
Optional binding is for checking if an optional contains a value to pass to a non optional parameter.
Upvotes: 2