Top Banner
var, let, & ? Optionals & Flow control around them Matt Faluotico
35

Optionals by Matt Faluotico

Apr 15, 2017

Download

Technology

WithTheBest
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Optionals by Matt Faluotico

var, let, & ?

Optionals & Flow control around themMatt Faluotico

Page 2: Optionals by Matt Faluotico

Matt Faluotico

● Midwest born and raised, Ohio State● iOS Developer at Xero (accounting SaaS)● Employee App● 3 years of iOS

● Twitter: @mattfxyz● Web: mattf.xyz● Github: /mattfxyz

Page 3: Optionals by Matt Faluotico

● Introductions● Objects● Var, Let, ● Optionals● Unwrapping● Implementing● Dependency injection● Conclusion● Q&A

Hello!

Page 4: Optionals by Matt Faluotico

Objects

Page 5: Optionals by Matt Faluotico

Objects in Swift

Everything is an object!

● Swift is still strongly typed, even if it doesn't quite look like it● Grew from C & Objective-C● Even primitives (Int, String, Bool, etc...)

Compiler will assume the type

var str = "Hello, With The Best" // Assumed to be a String

var specificStr: String = "Hello (again), With The Best"

Both are Strings!

Page 6: Optionals by Matt Faluotico

● Reassignable to other Strings

print(str.dynamicType) // => String

print(specificStr.dynamicType) // => String

● Because we used var

Objects in Swift

Page 7: Optionals by Matt Faluotico

var vs. let

Page 8: Optionals by Matt Faluotico

Keyword for declaring a mutable object

● If you’re going to reassign the object● If you’re using structs

var str = "Hello, playground"

str = "A different playground"

● Compiler is okay with this

var

Page 9: Optionals by Matt Faluotico

Keyword for declaring a constant object

● If you’re keep the same reference to an object● Your struct is not changing

let str = "Hello, playground"

str = "A different playground" // Compiler error

● Structs behave differently than classes

● Mutability is more defined by changing the pointer

let

Page 10: Optionals by Matt Faluotico

let for classes

class MyStruct {

var number: Int

var name: String

}

let c = MyClass(number: 0, name: "cat")

s.number = 12 // This is not mutating the class

● Changing the properties on the heap

Page 11: Optionals by Matt Faluotico

● Structs live on the stack○ Much faster

● But they have a constant size and are immutable● When you reassign to a struct, you create an entire new object on the stack

struct MyStruct {

var number: Int

var name: String

}

let s = MyStruct(number: 0, name: "cat")

//s.number = 12

● For structs this fails

let for structs

Page 12: Optionals by Matt Faluotico

Remember our string?

var specificStr: String = "Hello (again), With The Best"

var specificStr: String = nil

● This breaks the things...

Objects can’t be nil

Page 13: Optionals by Matt Faluotico

So we have Optionals

Page 14: Optionals by Matt Faluotico

● A traditional type must hold a value (cannot be nil)● An optional wraps any type in a form that allows nil

“there is a value, and it equals x” – Swift Programming Language

● We use the ? to declare something as an optional

var str: String? = "Hello, With The Best"

Optionals

Page 15: Optionals by Matt Faluotico

Why Optionals?

We know ahead of time if the object we're working with is capable of being nil and we can handle it appropriately.

● Why check to see if something is nil if it cannot be nil?● Let programmers consuming an API or library which parts are optional● Xcode's compiler leads to less mistakes● Objective-c compatibility: All pointers can be nil

We’ll always know if something could potentially be nil

Page 16: Optionals by Matt Faluotico

● Force Unwrapping (!)○ Returns the value, but the program will crash if nil is found○ Using ! is called “unsafe” but still commonly used○ For unwrapping causes a runtime error when the object is nil

var str: String? = "Hello, With The Best"

print(str!)

● Optional Chaining (?)○ Returns the value IFF the value exists○ Will only execute if the object can be unwrapped

■ Will return nil if it can’t be unwrapped

var str: String? = "Hello, With The Best"

var n: = str?.characters.count

Unwrapping Optionals

Page 17: Optionals by Matt Faluotico

● Should always unwrap optionals

let x = str?.characters.first

let a = str?.stringByAppendingString("cat")

let start = str?.startIndex

let end = str?.endIndex

● All of those question marks look messy● Everyone agrees

Unwrapping Optionals

Page 18: Optionals by Matt Faluotico

● if-let is the solution

if let s = str {

let x = s.characters.first

let a = s.stringByAppendingString("cat")

let start = s.startIndex

let end = st.endIndex

}

● If we can unwrap the object, bind it to an immutable value● Since they’re objects, all the changes affect both

Optional Binding

Page 19: Optionals by Matt Faluotico

Option Binding

if let s = aString,

let i = s.characters.count,

let b = aBool,

let f = aFloat {

print(s)

print(i)

print(b)

print(f)

print("everything was unwrapped!")

} else ...

● You can even check for multiple unwraps in one if-let statement● Use the previous unwrapped results in following conditions!● As soon as one value is nil, the condition is false

○ Handle that one with an else case!

Page 20: Optionals by Matt Faluotico

Left Hand Flow

Page 21: Optionals by Matt Faluotico

● Left should always be good● Ray Wenderlich says it best

“When coding with conditionals, the left hand margin of the code should be the "golden" or "happy" path. That is, don't nest if statements. Multiple return statements are OK”

● if-let puts the “happy” value on the left side, but it still requires nesting ifs

● Return early for readability

Left hand rule

Page 22: Optionals by Matt Faluotico

Guard

● Check for a condition that must be true to continue in the scope● If it’s true, continue

○ But… you must leave inside the else block○ That new variable is also available for the rest of the scope

func makeRequest(sessionManager session: SessionManager?) {

guard sm = session else {

return

}

sm.something()

}

Page 23: Optionals by Matt Faluotico

Implementation

Page 24: Optionals by Matt Faluotico

Optionals are actually just Swift enums

enum Optional<T> : Reflectable, NilLiteralConvertible {

case None

case Some(T)

init()

init(_ some: T)

}

● Initialized with a value or with an object● The None case is just nil

Implementation

Page 25: Optionals by Matt Faluotico

● Because they’re optionals, there are some cool thing we can do with them● A lower level version of if-let

○ Because if-let is just a shortcut

let someOptional: Int? = 42

if case Optional.Some(let x) = someOptional {

print(x)

}

if case let x? = someOptional {

print(x.dynamicType)

print(x)

}

Implementation

Page 26: Optionals by Matt Faluotico

Only continue if the value can be unwrapped

for case let x? in a {

print(x)

}

You can check for conditions in loops

for var x in a where x > 34 {

print(x)

}

(this one still iterates over nil)

Same for for loops

Page 27: Optionals by Matt Faluotico

Implicitly Unwrapped Optionals& “Dependency Injection”

Page 28: Optionals by Matt Faluotico

Master → Details(most applications)

Page 29: Optionals by Matt Faluotico

So you have a class...

class DetailViewController: UIViewController {

var username: String

var profilePicture: UIImage

...

}

Page 30: Optionals by Matt Faluotico

● “Class __ has no initializers”● All non-optionals must have values after initialization● View Controllers don’t always fill all of their properties in initialization

You know that the value isn’t going to be nil when you want to use it…

The “Master” Controller is going to provide it

But you get an error

Page 31: Optionals by Matt Faluotico

Let’s add optionals!

class DetailViewController: UIViewController {

var username: String?

var profilePicture: UIImage?

...

}

Page 32: Optionals by Matt Faluotico

Not you have to unwrap for every use…

Nah

Let’s add optionals!

Page 33: Optionals by Matt Faluotico

Implicitly Unwrapped Optionals

class DetailViewController: UIViewController {

var username: String?

var profilePicture: UIImage!

...

}

Page 34: Optionals by Matt Faluotico

● In between a traditional object and an optional● Most commonly used in multi-step-initialization● “Compiler Magic”

“An implicitly unwrapped optional is a normal optional behind the scenes, but can also be used like a non optional value”

● They’re dangers. Be careful out there

Implicitly Unwrapped Optionals

Page 35: Optionals by Matt Faluotico

Summary

● Type safe Swift● “Nil safe” from optionals● Left is happy● There’s a way around it