Swift Functions
Posted on Thu 13 February 2020 in swift
Onward to day 5 of 100 Days of Swift. Today was all about functions, and there were a few things that I didn't remember, mainly because I don't use them much when I code.
First up is variadic functions. I don't use these because I tend to use arrays when I need to pass in an arbitrary number of values of the same type. Because swift doesn't support splatting, you have to do this either as an array or with a variadic function, there's no way to safely do both at the same time without helper functions.
func todayISaw(_ taxa: String...) {
if taxa.contains("California Slender Salamander") {
print("Today was a good day!")
} else {
print("Better luck tomorrow.")
}
}
Another thing I've mostly forgotten about with Swift is function parameter default values. I use this feature a lot in python to provide sensible defaults for training parameters, like the number of epochs to run or the number of validation batches per validation pass.
func hike(whileMakingObservations: Bool = true) {
if whileMakingObservations {
print("What a lovely day!")
} else {
print("Why not?")
}
}
I also forgot about inout
parameters, I guess it's a feature that I don't really use and that I tend to code around. I think the main place I see it in Objective-C is with error handling. While the tutorials all use inout
to modify primitive values, that seems like a contrived example to me. Passing by reference, however, could be useful:
func makeObservation(taxon: String, lifeList: inout Set<String>) {
print("Nice \(taxon) sighting!")
lifeList.insert(taxon)
}
var lifeList = Set<String>()
makeObservation(taxon: "Toyon", lifeList: &lifeList)
makeObservation(taxon: "California Poppy", lifeList: &lifeList)
And one last thing that I didn't remember: using multiple catch blocks to handle different kinds of errors.
enum ObservationError: Error {
case NoTaxon
case NoDate
case NoGPS
}
func makeObservationFromDict(_ dict: Dictionary<String, Any>) throws {
guard dict["taxon"] != nil else { throw ObservationError.NoTaxon }
guard dict["date"] != nil else { throw ObservationError.NoDate }
guard dict["gps"] != nil else { throw ObservationError.NoGPS }
// make observation...
}
var obsDict: [String: Any] = ["taxon": "Genus Scaphinotus", "date": Date()]
do {
try makeObservationFromDict(obsDict)
} catch ObservationError.NoTaxon {
print("Please tell us what you saw.")
} catch ObservationError.NoDate {
print("Please tell us when you saw it.")
} catch ObservationError.NoGPS {
print("Please tell us where you saw it.")
}
Today's annoyance: the iPad Playgrounds Swift runtime crashed when I was 90% done with the day's lesson. I had to reset (in app, I never closed the Playgrounds app), and it deleted the entire page of code. I'm now looking very suspiciously at this text/code editor which can delete my work without warning.