Equivalence of short-cut optional binding syntax i

2019-06-02 04:36发布

问题:

Given

var maybeInt: Int?

how to the following two conditional statements differ?

// (1)
if let y = maybeInt {
    y
} else {
    println("Nope")
}

// (2)
if let y = maybeInt? {
    y
} else {
    println("Nope")
}

They seem to behave exactly the same. Is the former a short-cut for the latter?

回答1:

The second syntax is optional chaining — just with nothing after the chaining operator. It accesses whatever optional comes before it (if the optional is not nil), allows chaining property accesses or method calls on the optional's contents, and wraps the result in an optional. Putting it in an if let unwraps that optional.

In other words, the additional ? in the second syntax is effectively a no-op here.


However, though it has no effect in your example, ? on its own is still doing optional chaining, as you can see with

if let y: Int? = maybeInt {
    y
} else {
    println("Nope")
}

if let y: Int? = maybeInt? {
    y
} else {
    println("Nope")
}

which results in

nil
"Nope"

because while maybeInt? == maybeInt — a "no op", in the sense above — (and an assignment of nil to an Int? works) the second expression encounters nil on the optional chaining of maybeInt and fails.