Structs, Part 1

Hey guys, it’s Alex!

Another 100 Days of Swift blog post, this morning I was working through Day 8, Structs part 1. Once again I was aware of the basics of structs, having used them quite a bit, but I still learned a bunch from today’s exercises.

The first thing that was new to me was property observers in structs. This seems like a feature that I’ll get a lot of mileage out of:

struct ImageClassifier {
    var fps = 60
}

struct Camera {
    var classifier: ImageClassifier
    var fps: Int {
        didSet {
            classifier.fps = fps
        }
    }
}

Something else new to me was mutating methods on structs. Since at struct definition time, Swift won’t know whether a struct is a constant or a variable, you can use this hint so that Swift knows that your mutating method will only be callable on variable instances of this struct:

struct Artwork {
    var title: String
    var artist: String
    var isSold: Bool
    var owner: String?
    
    mutating func sold(to newOwner: String) {
        isSold = true
        owner = newOwner
    }
}

var jetFighter = Artwork(title: "Düsenjäger", artist: "Gerhard Richter", isSold: false, owner: nil)
jetFighter.sold(to: "Zhang Chan")
jetFighter.sold(to: "Cheyenne Westphal")

I’d never really given much thought to what type strings or arrays are in Swift. I think I assumed that strings were probably classes, based on NSString but it’s cool to see that they’re structs. Swift arrays, tho, had me totally fooled. Was it based on NSArray, or was it a base data type of the language like C arrays, or something else? I have to admit I’d never thought about it, so it was cool to learn that Swift arrays are also structs. Since Swift is open source, including the standard library, you can actually find the definitions here and here. Yep, they’re structs.

I also learned two methods, one on string and one on array, that I think I’ll use. First, string’s hasPrefix() method will come in handy:

let courseSchedule = [
    "CS 101",
    "CS 232",
    "HSTEU 401",
    "HSTAA 299",
]

let csClasses = courseSchedule.filter {
    return $0.hasPrefix("CS")
}

Also, I’ll be using the array method firstIndex(of:) instead of index(of:) since the latter has been deprecated. Here’s a kind of made-up example from how you might implement part of a UIPageViewController which also shows endIndex and index(after:):

func pageViewController(_ pageViewController: UIPageViewController,
                        viewControllerAfter viewController: UIViewController) -> UIViewController? {

    guard let currentIdx = orderedViewControllers.firstIndex(of: viewController) else {
        assert(false, "couldn't get idx of a view controller in orderedViewControllers")
        return nil
    }
    
    if (currentIdx == orderedViewControllers.endIndex) {
        return nil
    } else {
        let nextIdx = orderedViewControllers.index(after: currentIdx)
        return orderedViewControllers[nextIdx]
    }
}