Optionals must be unwrapped before they can be used in most expressions. if let
is an optional binding, which succeeds if the optional value was not nil
:
let num: Int? = 10 // or: let num: Int? = nil
if let unwrappedNum = num {
// num has type Int?; unwrappedNum has type Int
print("num was not nil: \(unwrappedNum + 1)")
} else {
print("num was nil")
}
You can reuse the same name for the newly bound variable, shadowing the original:
// num originally has type Int?
if let num = num {
// num has type Int inside this block
}
Combine multiple optional bindings with commas (,
):
if let unwrappedNum = num, let unwrappedStr = str {
// Do something with unwrappedNum & unwrappedStr
} else if let unwrappedNum = num {
// Do something with unwrappedNum
} else {
// num was nil
}
Apply further constraints after the optional binding using a where
clause:
if let unwrappedNum = num where unwrappedNum % 2 == 0 {
print("num is non-nil, and it's an even number")
}
If you're feeling adventurous, interleave any number of optional bindings and where
clauses:
if let num = num // num must be non-nil
where num % 2 == 1, // num must be odd
let str = str, // str must be non-nil
let firstChar = str.characters.first // str must also be non-empty
where firstChar != "x" // the first character must not be "x"
{
// all bindings & conditions succeeded!
}
In Swift 3, where
clauses have been replaced (SE-0099): simply use another ,
to separate optional bindings and boolean conditions.
if let unwrappedNum = num, unwrappedNum % 2 == 0 {
print("num is non-nil, and it's an even number")
}
if let num = num, // num must be non-nil
num % 2 == 1, // num must be odd
let str = str, // str must be non-nil
let firstChar = str.characters.first, // str must also be non-empty
firstChar != "x" // the first character must not be "x"
{
// all bindings & conditions succeeded!
}