Swift

Optionals

To be or not to be

You can trust Swift

Swift is a very safe language, so it is always making sure your code never fails. That’s one of the things that make it stand out over other languages.

An optional basically tells a function "You might return this, you may not". It’s a safe way to control what exactly is being returned.

func weatherReport(for temperature: Int) -> Int? { // the ? tells the code, that it's optional
    if temperature > 80 {
        return temperature
    } else {
        return nil // this means "no value"
    }
}

This code takes in an Integer, and if that integer is not above 80, it returns nil, or no value. Since we told the function that we have an optional, Swift won’t be upset. Let’s see what value comes out.

var temp: Int? // may be an Integer, may not
temp = weatherReport(for: 60)

Now, what do we even do with this? We will do something called unwrapping. This means to find the value, then do something afterwards. We will be using something fancy, called an if let.

if let temp = weatherReport(for: 60) {
    print("It's hot!")
} else {
    print("It's cold!")
}

Basically, in plain english: If we let temp equal weatherReport(for: 60) and it’s an Int, print “It’s hot!". If it is nil/optional, print “It’s cold!".

This is a hard concept to master, so make sure you understand it.

Force unwrapping

Force unwrapping is when we need to override Swift’s safety. If we know that the optional will have a value, adding a ! after the variable will unwrap it.

Here's an example

func daysPerMonth(in month: String) -> Int? {
    if month == "January" { return 31 }
    if month == "February" { return 28 }
    if month == "March" { return 31 }
    if month == "April" { return 30 }
    if month == "May" { return 31 }
    if month == "June" { return 30 }
    if month == "July" { return 31 }
    if month == "August" { return 31 }
    if month == "September" { return 30 }
    if month == "October" { return 31 }
    if month == "November" { return 30 }
    if month == "December" { return 31 }
    return nil // if no correct months are in, return nil
}
    
var days = daysPerMonth(in: "Julianuary")
    
If days == nil {
    print("That's not a real month.")
} else {
    print("That month has \(days!) in it.") // force unwrapped
}

Optional Chaining

Swift has two ways of making your code less complicated with optionals. The first is called Optional Chaining. Let’s look at the code below.

func daysOfTheWeek(day: Int) -> String? {
    switch day {
        case 1: return "Monday"
        case 2: return "Tuesday"
        case 3: return "Wednesday"
        case 4: return "Thursday"
        case 5: return "Friday"
        case 6: return "Saturday"
        case 7: return "Sunday"
        default: nil
    }
}
        
let day = daysOfTheWeek(day: 3)
print("It's \(day) my dudes!")

We have multiple issues here. First of all, what gets printed is different from what we programmed. We see “It’s Optional(“Wednesday") my dudes!". Another issue is if we type in a case that isn’t considered, the default case takes over, resulting in day = nil.

Let’s make our day variable lowercase and see what happens. This is where we use chaining. Since we can’t be sure that day will equal a String, we need to change it so if it’s a String, it becomes lowercase.

let day = daysOfTheWeek(day: 3)?.lowercased()
print("It's \(day) my dudes!")

With the ?, we can add new values to apply, but only if this value isn’t an optional. While we are able to make sure we can lowercase the String, we still can’t remove that Optional surrounding our variable. There’s a fix for this.

The Nil Coalescing Operator

Whoa, that’s a big term. This easy Swift feature allows us to fix all of these problems. By adding ?? afterwards and another value, we can tell Swift this: If day is equal to nil, let’s make it equal to “Today”.

let days = daysOfTheWeek(day: 8)?.lowercased() ?? "Today"
print("It's \(day) my dudes!")

To be or not to be?

And just like that, all of our problems are fixed. Optionals are a large concept to understand, so it’s important you understand how they work. These next few lessons are all about creating new definitions, data, and information.

chevron_up