Optionals

Whew, I’m running a little behind. It’s Tuesday, and I’m just now writing the recap for the work that I did yesterday. Yesterday, I caught up and wrote a recap of the work from Sunday. My goal for the night is to recap yesterday and today’s work, so that I’m back on track for the rest of the week.

Anyways, on to optionals in Swift, day 12 of 100 Days of Swift. Once again a few new things, some small bits that I’d seen before but hadn’t ever thought about, and a few bigger gaps in my knowledge that was great to close up a bit.

First, the easy stuff: I had seen the optional try? syntax before, maybe copy/pasted it from a tutorial or something, but I hadn’t really understood what it does. Turns out it executes some code that might throw an error, returning either a nil value if the code threw, or some actual value if the code didn’t throw an error. If you don’t care about the error that might be thrown, and just want to know if it succeeded or not, this might be a good option. Another simple thing, I didn’t realize you can use guard without let if you’re testing a condition.

A bigger piece of Swift that I’d come across on Day Two but had already completely forgotten was nil coalescing with the ?? operator. It’s kind of a default value for an optional.

Finally, something that I’ve used in Objective-C, optional initializers, showed up in Swift today. Here’s an example that also illustrates almost everything I know about coffee:

enum Roast {
    case Unroasted
    case LightRoast
    case DarkRoast
}

enum Origin {
    case Ethiopia
    case LatinAmerica
}

struct Beans {
    var origin: Origin
    var roast: Roast
    
    mutating func roast(_ roast: Roast) {
        self.roast = roast
    }
}

struct BrewedCoffee {
    var caffeine: Int
    var flavor: String
    init?(beans: Beans) {
        switch beans.roast {
        case .DarkRoast:
            self.caffeine = 10
            self.flavor = "Rich"
        case .LightRoast:
            self.caffeine = 12
            
            switch beans.origin {
            case .Ethiopia:
                self.flavor = "Fruity"
            case .LatinAmerica:
                self.flavor = "Chocolatey"
            }
        case .Unroasted:
            print("You can't brew unroasted beans!")
            return nil
        }
    }
}

var beans = Beans(origin: .Ethiopia, roast: .Unroasted)
beans.roast(.LightRoast)
var cup = BrewedCoffee(beans: beans)
cup?.flavor