Why does Swift's optional binding succeed with 'nil' in certain cases?

故事扮演 提交于 2020-01-10 04:30:07

问题


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)?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/26576366/why-does-swifts-optional-binding-succeed-with-nil-in-certain-cases

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!