Introduction to Optionals (Part 1)
Yes - one day's break, but not because I needed or wanted one! I was genuinely to busy for any Swift yesterday, so it feels good to be back! Having written entries each day for a week, I missed it! Enumerations are done for now; Optionals are next...
The Absence of Data
I think the idea of this is 'nil' - nothing! Pasan explains 'safe' code, where crashes need to be avoided. Optionals are new - since the inception of Swift I believe.
struct Person {
let firstName: String
let middleName: String?
let lastName: String
}
I've pre-empted the ? - to make middleName an optional. If I didn't have this, then an error would be caused - you can't input nil. The question mark - making it an optional - means that nil CAN be used. So it means it may have a value OR may be nil. They do seem cumbersome, but apparently they are powerful and useful! In the example above, it means that it is a string and may hold a value, or it may contain no value (nil). It can't contain anything else - not a Bool, Int etc. That makes a little more sense!
Technically optionals are types of Enums! Something to do with 'generics', but Pasan does not go into detail. An optional is an enum with two values - none and some! If a value exists, the compiler returns the associated value. Interesting how even built-in features have details 'under the covers'.
Working with Optional Types
What are the uses of optionals? Pasan shows an 'Objective C' example - how you cannot tell if the value might be nil. Having to manually open the variable/constant each time.
A String and optional String are not the same type! We need to UNWRAP it - using the value inside, if it exists.
Pasan shows one way - using 'if middleName == nil', then returning the name with the middle name. This from what I remember is 'safer', but you can also use the ! after the variable....that's what I have done for now!
struct Person {
let firstName: String
let middleName: String?
let lastName: String
func fullName() -> String {
return firstName + " " + middleName! + " " + lastName
}
}
let me = Person(firstName: "Josh", middleName: nil, lastName: "Gonet")
me.fullName()
OK...Pasan says NEVER to do that! It's called force unwrapping - it's bad code. It works but it's not guaranteed. Force unwrapping is very unavoidable. Only worry about this when it is useful!
Optional Binding
Dictionaries always return an optional value - in case the key does not return a value.
let airportCodes = ["CDG": "Charles De Gaulle"]
let newYorkAirport = airportCodes["JFK"]
if let newYorkAirport = airportCodes["JFK"] {
print(newYorkAirport)
} else {
print ("That key does not exist!")
}
In this example, the value is not force unwrapped - it is far safer this way.
let formulaDictionary: [String: [String: String]] = [
"novice": ["Verstappen": "3 wins"]
"successful": ["Button": "17 wins"]
"master": ["Schumacher": "91 wins"]
]
if let successfulDriver = formulaDictionary["successful"], let highNumberWins = formulaDictionary["Schumacher"] {
print(highNumberWins)
}
I've deliberately done a different example to Pasan (f1 related!) as that's a more active way of learning. Initially, he had two separate if statements running, but that is unnecessary and Swift has evolved so they can be on one line.
let movieDictionary = ["Spectre": ["cast": ["Daniel Craig", "Christoph Waltz", "Léa Seydoux", "Ralph Fiennes", "Monica Bellucci", "Naomie Harris"]]]
var leadActor: String = ""
// Enter code below
if let movie = movieDictionary["Spectre"], let cast = movie["cast"] {
leadActor = cast[0]
}
The challenge here was to use optional binding to add the value of Daniel Craig to a variable. I got close, got some help but Xcode still did not like it! Still, it was the correct answer. What I missed was creating constants for each element of the dictionary - Spectre then Cast. I'll remember that but it's a bit disconcerting that it did not work on Xcode!
That will do for now. Optionals are making more sense - especially the reasoning behind them. Optional Binding is more logical than I thought and I can take away from this never to use ! (not for now at least) and that the code needs the binding in order to work smoothly. Until next time!
Comments
Post a Comment