Optional Unwrapping for the More Curious

Did you know? T? is syntactic sugar for Optional<T>, where T denotes a concrete type, such as Int, Double, String, or even FooBar.

For example, these two variable declarations have the same effect.

var powerOf2 : Int? = 1
var powerOf2 : Optional <Int> = 1

Note: In the standard library, the generic type Optional is defined like this:

enum Optional <T> {
    case none
    case some (T)
    public init (_ value: T)
}

Extracting values from optionals, there are several ways.

Given one of these declarations:

var powerOf2 : Int? = 1
var powerOf2 : Optional <Int> = 1

Extract value by force, unsafe way:

let v = powerOf2!
// If the value of powerOf2 is nil
// you will get the notoriuos fatal error: unexpectedly found nil while unwrapping an Optional value

print ("power of 2 = \(v)")

Extract value by force, safe way:

if powerOf2 != nil {
    let v = powerOf2!
    print ("power of 2 = \(v)")
}
else {
    print ("power of 2 is not set")
}

There are other safe and more acceptable ways.

Extract value by optional binding, the standard, canonical way:

if let v = powerOf2 {
    print ("power of 2 = \(v)")
}
else {
    print ("power of 2 is not set")
}

Extract value by using a switch statement:

switch powerOf2 {
case .some (let v):
    print ("power of 2 = \(v)")
case .none ():
    print ("power of 2 is not set")
}

Extracting values by using optional patterns.

Extract by using an enumeration case pattern:

if case .some (let v) = powerOf2 {
    print ("power of 2 = \(v)")
}
else {
    print ("power of 2 is not set")
}

Extract by using an optional case pattern:

if case let v? = powerOf2 {
    print ("power of 2 = \(v)")
}
else {
    print ("power of 2 is not set")
}

Extracting values from an array which may contain nils.

let powerOf2Vector : [Int?] = [1, nil, 4, 8, nil, 32, nil, 128]

Extract value by optional binding:

for powerOf2 in powerOf2Vector {
    if let v = powerOf2 {
        print ("power of 2 = \(v)")
    }
    else {
        print ("power of 2 is not set")
    }
}

Extract by using an optional case pattern:

for case let powerOf2? in powerOf2Vector {
    print ("Got a power of 2 = \(powerOf2)")
}

Extract by using an enumeration case pattern:

for case .some (let powerOf2) in powerOf2Vector {
    print ("Got a power of 2 = \(powerOf2)")
}

Become a competent programmer faster than you can imagine.