In swift the following syntax is allowed for flow control
if let constantName = someOptional {
statements
}
In this context wh
Optional chaining example :
let object : Int ? = 3
if (object =! nil) { print (object! as Any)
}
if let objOptChaining = object { print(objectChaining)
}
Optional Binding Example :
let object : Int ? = 3
if let objOptBinding = object{
// objOptBinding hold the value
} else {
// no value }
You can't chain the optional binding like this:
if let constantName = someOptional && constantName = someOptional2 {}
but in Swift 1.2 you can write this:
if let constantName = someOptional, constantName = someOptional2 {}
What's going on here?
Optionals are their own type and are Swift's way of providing compile time checking for nil
. When you type var potentialValue : Int?
you are not using some special Int, you are using the Optional type, which is essentially an empty enum. This is why you often have to unwrap the optional with the !
as this allows you to access what's inside (if there is anything inside). If the optional contains no value (i.e. the enum is empty) then it has a value of None
. If the optional is not empty then it has a value of Some
and an associated value of whatever type you are using - so in this case an Int.
This:
if (someOptional != nil){
let constantName = someOptional!
}
is the same as using this:
if let constantName = someOptional {}
which is called optional binding. You'll notice that the second version here is a little more readable and you don't have to explicitly unwrap the optional using the !
.
It evaluates to true when the optional's value is Some
and not None
- in other words, when the optional is not nil. (Notice that you can still check for nil
if you like and you can also change an optional's value back to None
by writing someOptional = nil
.
Something else that hasn't been mentioned is that you can use ??
(called the nil coalescing operator) to give an optional a default value if it doesn't have one. For example:
let constantName = someOptional ?? 100
Here someOptional
will be unwrapped if it has a value but if it doesn't then the value 100
is used instead.
I find it useful to remember that optionals are their own type in Swift. They aren't a fancy version of the type that you are saying they contain.
The optional binding
Swift 2
if let constantName = someOptional, constantName2 = someOptional2 {
// your statement goes here .....
print(constantName)
print(constantName2)
}
swift 3
if let constantName = someOptional, let constantName2 = someOptional2 {
// your statement goes here .....
print(constantName)
print(constantName2)
}
First someOptional
is checked to see whether or not its nil
. If its not, then constantName
is assigned to the unwrapped value of someOptional
. If its nil
, it goes to the else
statement.
This means, that even if someOptional
is a Bool?
which is assigned to false
, it will still go into the first block, not the else
.
The Intermediate Swift
video goes into much depth on this topic, in the first 15 minutes!
From the Apple Doc
Optional Binding
To conditionally bind the wrapped value of an Optional instance to a new variable, use one of the optional binding control structures, including if let, guard let, and switch.
if let starPath = imagePaths["star"] {
print("The star image is at '\(starPath)'")
} else {
print("Couldn't find the star image")
}
Optional Chaining
To safely access the properties and methods of a wrapped instance, use the postfix optional chaining operator (postfix ?). The following example uses optional chaining to access the hasSuffix(_:) method on a String? instance.
if let isPNG =imagePaths["star"]?.hasSuffix(".png") {
print("The star image is in PNG format")
}
// Prints "The star image is in PNG format"
if let constantName = someOptional {
statements
}
Basically what is happening here is that if someOptional has a non-nil value, constantName is assigned someOptional value for the scope of this if-statement.
In terms of semantics, the order of how things happen is A) someOptional is checked for nil, B) and then it is assigned to constantName, and then finally, C) statements in the if-block are executed.
Usually, the value of doing something like this is that it prevents the app from crashing if you otherwise have a nil-value. It is worth noting that the nil in Swift if different from Objective-C because it is more powerful than simply a pointer.
Also, if someOptional is a Bool that is False, do note that it will still execute that if-block because it is not checking for true/false but rather the presence/absence of value. The presence of False renders the if-block true.