Swift Docs: A Swift Tour Flashcards

1
Q

What is a constant? How do we declare one?

A

Declare using let. Constants have their value set exactly once, but may be used many times. Constant values do not need to be known at compile.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is a var? How do we declare one?

A

Declare using var. Vars may change, may be computed, and and do not need to be known at compile.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

How does type inference work in Swift? How do you manually declare type?

A

Swift uses advanced type inference, so type declaration is not required unless the value is ambiguous to type (e.g. your value is 70.23, but you don’t want a double, you want a string).

Manually declare with var value: Double = 70.23

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

How do you type cast (explicitly convert to another type) in Swift? Cast name = “Dave” and value: Double = 70.23 into a single string.

A

”(name) has (String(value)) shares of Apple stock”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Swift offers a simpler way to cast a double or non string into a string. Use it to cast name = “Dave” and value: Double = 70.23 into a single string.

A

print(“(name) has (value) shares of Apple stock”)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

How do we create a quotation in Swift? Supply code for “The only thing we have to fear is fear itself”.

A

Using double quotation marks at the beginning and end.

let quote = “””
The only thing we have to fear
is fear itself.
“””

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How do we create an array in Swift? Create an array called shoppingList with Tomatoes, Beans, and Milk. Then add lemons to it as a second index element, and add bananas to it as the end index element.

A

We create using brackets, and, if we want to supply values, listing them inside.

var shoppingList = ["Tomatoes", "Beans", "Milk"]
shoppingList[1] = "Lemons"
shoppingList.append = "Bananas"
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What is a dictionary, and how is it different but similar to an array?

A

Both Arrays and Dictionaries store series of values of like types. Arrays, however, index all values against a numerical index value starting at zero. Dictionaries allow you to specify Key/Value pairs, so you can customize the ‘key’ part of the equation.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Create a dictionary, called occupations, which stores Dave as Programmer, Sam as a banker, and Rick as a Marketer. Then add Evan as an engineer.

A
var occupations = [
   //"Key": "Value"
   "Dave": "Programmer",
   "Sam": "Banker",
   "Rick": "Marketer"
]

occupations[“Evan”] = “Engineer”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Create an emptyArray and an emptyDict, both of type String

A

let emptyArray = String

let emptyDict = String: String

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What is a For-In Loop? How do we use one to cycle through an array called dealValue?

A

For in allows us to programmatically cycle through values. For example, we could say “for x in dealValue…” which will use x to increment through the dealValue array.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What is a Switch? What is required to use one? Show how you’d cycle through it.

A
A switch allows you to define conditional logic based on 'cases'. For example we could say the following: 
let vegetable = "red pepper"
switch vegetable {
case "celery":
    print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
    print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):
    print("Is it a spicy \(x)?")
default:
    print("Everything tastes good in soup.")
}
Note you need a "default" case. It must be "exhaustive".
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What is an optional, and what is the syntax? What is returned if an optional is not set at runtime?

A

An optional is an optional value - it allows you to invoke a var or let which may or may not be defined at runtime without destroying your app if it’s not set. If it’s not set, it returns nil. The syntax is let name: String? and then = the value it holds IF it is set.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What is the syntax for Optionals and Default Values? What is the logic here?

A

You use the optional first, followed by ??, followed by the default value;

print(“Hello, (nickname ?? realName)”), with nickname being the optional, and realName being the default value.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What data types do IF statements work with?

A

IF statements only work with equality comparisons and strings/ints. This is a nice aspect of switches, as they allow you to handle any kind of data type.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

How do we use a For In loop with a dictionary, as opposed to any other value type?

A

Dictionaries are unique value types because they contain two value sets, keys and pairs. Normally with a for in loop we say “for x in y…”, but for a dict, we scan it using for (thing1, thing2) in y, where thing 1 is what you’re going to scan your keys with, and thing 2 being what you scan your values with.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

How do we use a While loop? How can it be used in conjunction with Repeat, and how is this different from If?

A

While allows you to run syntax so long as a condition continues to be true. When we pair it with Repeat, and use While after the repeat logic, it lets us ensure the logic is run at least once.

Example:
var z = 101
repeat { 
  z *= 2 } while z < 100
print(z)

This will print 202. Because 101 will be multiplied by 2 once, since the while condition is after the logic. Alternatively, you can use it before the logic on its own:

Example: 
var x = 2
while x < 100 {
 x *= 2
}
print(x)

This will print 128. The loop runs 6 times (4–>8–>16, so on).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

What is the syntax to run a range UP TO the specified value, and what is the syntax to run a range INCLUDING the specified value?

A

Use “0..<3” to run a range of 0, 1, 2.

Use “0…3” to run a range of 0, 1, 2, 3.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

How do we declare a function?

A

Use the func syntax, followed by parameters and their types in parenthesis separated by commas, and using an arrow to separate the parameters from the return type, followed by brackets.

“func functionName(parameter1: String, parameter2: Int) -> ReturnType { }”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Explain how functions can have internal and external parameter names, and the associated syntax. Also explain how you can have no external name for an argument.

A

We can specify a custom argument label before a parameter name in the parenthesis when defining a function. External name always comes first. You can also use _ to specify no external name.

func example(externalParamName internalParamName: String, _ secondParam: String)

In the above example, we’d use “internalParamName” and “secondParam” inside of the function’s code to reference our parameters, but we’d use “externalParamName” and blank while supplying the arguments in an external call to the func.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

What exactly is the difference between parameters and arguments for a function?

A

Parameters are what you specify as inputs when defining a func, like func test(param: String)

Arguments are what you SUPPLY to the func when running it or passing it, like into a var. So I would pass an argument into “param” when using the function.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

What is a Tuple? Write the syntax for a tuple with min, max, and sum.

A

A Tuple is a compound value, or, put another way, a means of extracting multiple returns from a function.

func math() -> (min: Int, max: Int, sum: Int) { }

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

What happens when functions are nested?

A

Functions can be nested inside of one another. A nested function can access the vars from its parent/external function.

func giveMe30() -> Int {

    var z = 20
    func addTen() {
       z += 10
    }
    addTen()
    return z

}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

What does Swift treating funcs as First Class Types mean?

A

First class types can be returned by a function. (like how a func can return a String, Int, Bool, etc). In Swift, Func is equivalent in type to any of these. So that means…functions can return other functions.

func firstClassFuncs() -> ((Int) -> Int) {

func increment(y: Int) -> Int {
        var x = y
        x += 1
        return x
}

return increment

}

let number123 = firstClassFuncs()
print(number123(10)) // prints "11"
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

Explain how functions can take funcs as arguments in Swift. What is the syntax for doing so?

A

In Swift, functions can both take funcs as arguments, and return funcs as returns. Syntax is identical to supplying a “regular” argument, you just list its name (e.g. passedFunc:) and then it’s arguments and returns (e.g. passedFunc: (Int) -> Bool

An example, where “condition” is a argument func.

func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {

    for item in list {
        print(item)
        if condition(item) {
            return true
        }
    }
    return false

}

func greaterThan10(number: Int) -> Bool {

if number > 10 {

    return true
}
return false }

let array = [3]
hasAnyMatches(list: array, condition: greaterThan10)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

What is a closure? Give an example.

Regarding other funcs and vars, what does a closure have access to as far as scope?

A

A block of code that can be called later. A function is an example of a closure.

Closures have access to any vars and funcs available at the scope where they are defined, even if the closure is run at a later time in a different scope. We saw this already with nested functions.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

What is the syntax for an unnamed closure?

A

Closures do not need to be named. All you need is arguments and returns inside of ({ followed by in. Example:

let isOdd = ({ (number: Int) -> Bool in 
...code...
})
28
Q

It’s extremely common in Swift for coders to omit a lot of things when writing a closure. How can you simplify the syntax of a closure to the minimum amount of code?

A

Swift’s powerful type inference allows us to remove the argument type, return type, and return syntax, along with the return arrow.

So, we could turn this 
let isOdd = ({ (number: Int) -> Int in 
return number * 3
})
Into this...
let isOdd = ({ number in number * 3})

So what you’re seeing here is the argument name only, followed by in, followed by your closure’s logic without the “return” syntax. Swift knows the type of your argument and the type of your return by the fact you’re doing math with an integer in the code block.

29
Q

How can we use simplified functions with a delegate?

A

In Swift, we can use the same simplified function syntax with delegate functions. We can omit the argument type (it’s inferred), the return type, and the “return” syntax.

Example:
var values = [20, 30, 40, 100]
let mappedValues = ({ value in 3 * values}) // prints each value multiplied by 3
30
Q

What happens syntactically when the only argument to a function is a closure or func?

A

When this happens, you can omit the parenthesis that would normally go around a closure, all you need are the function brackets. For example:

let values2 = [100, 37, 200, 300, 50]
let sortedValues = values2.sorted { $0 > $1 }
print(sortedValues)
31
Q

In Swift we often see things like “$0” and “$1” in closure brackets - what is this?

A

This is shorthand argument syntax. In Swift, we’re allowed to use this shorthand, starting from $0 and counting up with each additional argument, to refer to the arguments passed to a func.

Example: Sorted is a function that takes two ints. Here, we’re able to just say $0 and $1 to refer to these two ints, rather than having to use more syntax to declare them.

let values2 = [100, 37, 200, 300, 50]
let sortedValues = values2.sorted { $0 > $1 }
print(sortedValues)
32
Q

What is a Class, and how do we declare one named Shape?

A

A class is a data structure which is passed around in memory via pointers, and which contains a set number of properties (vars, constants, and functions). In Swift, Classes do not give us a free init, meaning we have to instantiate and declare all of our vars before a Class can function, either through explicit declaration or an init.

class shape {
  var numberOfSides = 4
}
33
Q

Let’s say you want to use your “Shape” class and it’s buildShape function. How would you do this?

A

First, you have to create an instance of that class on a var and init it with (). Then, we can use functions from the class on the var using .function syntax

var thing = Shape()
thing.buildShape(arguments...)
34
Q

What is an init?

A

An init is a dedicated closure which simply initializes a class or struct’s properties. It allows us to set the properties of our class dynamically, rather than having to hardcode their values within the class.

The arguments of an init are passed like a function call when you create an instance of the class.

35
Q

What is a subclass? How does it relate to a superclass? How does it handle its own vars and those of its superclass?

A

A subclass is exactly what it sounds like - it conforms to the type of its superclass, but it can also have its own vars and functions. The appeal of a subclass is it can inherit all of the things from its superclass without needing to declare them again.

Take, for example, the superclass NamedShape and its subclass Square. Notice how Square can use it’s superclass’ vars, and override its function to not have to declare things over and over.

class NamedShape {
    var numberOfSides: Int
    var name: String
init(numberOfSides: Int, name: String) {

    self. numberOfSides = numberOfSides
    self. name = name

}

func simpleDescription() -> String {

    return "A \(name) shape with \(numberOfSides) sides"

}

}

class Square: NamedShape {

var sideLength: Double
    //init, from first to last, my local vars in the subclass, and then my superclass vars in the order they're in in the superclass.
    init(sideLength: Double, numberOfSides: Int, name: String) {
    self. sideLength = sideLength
    super. init(numberOfSides: numberOfSides, name: name)

}

override func simpleDescription() -> String {

    return "A \(name) with \(numberOfSides) sides and a side length of \(sideLength) each."

}

}

var squareThing = Square(sideLength: 10.2, numberOfSides: 4, name: "Square")
print(squareThing.simpleDescription())
36
Q

Let’s say we have a subclass named newThing and a superclass named Thing. newThing has a var called x, and Thing has 2 properties, a var a, a var b, (all strings) and also a func called simpleDescription.

First, tell me how you’d initialize both the subclass and superclass vars.

Then, tell me how you’d change how the function from the main class works in the subclass.

A

Inits:

init(x: String, a: String, b: String) {
self.x = x
super.init(a: a, b: b)
}

override func simpleDescription {

}

37
Q

What are getters and setters, and what do they allow us to do?

A

Getters and setters (get and set) are closures that are specifically used to GET the value of a computed property or SET the value of a property and associated properties.

Get and set do not have to be used together

A very simple example. Here, we are initially supplying a and b as init arguments to the class. Using our Get closure, we can now get the value of result. But, we can also use our set function to give B a new value (and ‘set’ a value for result) at the same time.

class Math {

var a: Int
var b: Int

init(a: Int, b: Int) {
    self.a = a
    self.b = b
}

var result: Int {

    get {

        return a + b

    }

    set {

        b = newValue - a

    }
}

func simplePrinter() -> String {

    return "Your result is \(result), which is \(a) + \(b)"

}

}

var equation = Math(a: 5, b: 3)
equation.simplePrinter()
equation.result = 10
print(equation.b) // prints 5
38
Q

What are the two ways we can set a new value with Set?

A

One is the default syntax, where newValue is the stand in for the variable. But you can also manually cite the variable name in the setter. This requires you to wrap the set closure name in a parenthesis, which default value does not.

set {
newValue…
}

set (mileTime) {
mileTime…
}

39
Q

How do we update a value when another value is set/updated?

A

Using willSet and didSet. The code you provide runs any time the value changes outside of an initializer.

Imagine you have a class called TriangleandSquare, which always wants to keep the side of a triangle = to the side length of the square.

Using willset, you can say, if the sideLength of one is updated, update the other one.

class TriangleAndSquare {

var triangle: EquilateralTriangle {
   willSet {
      square.sideLength = newValue.sideLength
   }
}
var square: Square {
  willSet {
    triangle.SideLength = newValue.sideLength
  }
}
}
40
Q

What is an optional in Swift?

A

In Swift we can use optionals to create a failsafe for a property which we don’t know 100% if we’ll have at runtime or not.

An optional is a type in Swift, just as Strings and Ints are.

Let’s say we might have a user’s name at runtime, but we might not. We want to use this potential name in lots of places, but we also need to know our program won’t crash if the name isn’t supplied.

var name: String?

41
Q

What is an Enum?

A

An enum is a common type for a group of related values.

Enums enable us to work with these related values in a type-safe way.

At its most basic level, it is a type of var which is specifically used with Switch and Conditionals.

42
Q

Give an example of how you’d build an enum for card ranks, from ace to king.

  • Name it Rank, with type Int
  • Create a func, simpleDescription, that returns a string with the description of each card (e.g. “King” for a king).
A

enum Rank: Int {

case ace = 1
case two, three, four, five, six, seven, eight, nine, ten
case jack, queen, king

func simpleDescription() -> String {

case ace:
 return "ace"
case jack:
 return "jack"
case queen:
 return "queen"
case king:
 return "king"
default:
 return String(self.rawValue)
}

}

43
Q

Unless explicitly specified, what is the rawValue assigned to Enum cases?

A

It starts from zero. So if you have an enum with 6 cases, their rawValues will be 0-5.

44
Q

What types can be used for Enum’s rawValues?

A

Integers, Floats, and Strings.

45
Q

How can we make an instance of an enum from a rawValue?

A

Using the init(rawValue:) syntax. Something like…

if let convertedRank = Rank(rawValue: 10) {
let goodCard = convertedRank.simpleDescription()
print(goodCard) // prints "ten"
}
46
Q

What is the relationship between the case values of an Enum and their raw values?

A

Case values are ACTUAL VALUES, not simply another way of referencing the raw values. In cases where no meaningful raw value is necessary, you simply don’t need to supply one.

Example:

enum Suit {
case hearts, diamonds, spades, clubs
}

47
Q

What is the difference between an Enum rawValue and Associated Value?

A

Typically, when we declare an Enum, and declare its cases, we declare their rawValues. These values are persistent - meaning the rawValue of a case will always be the same, no matter how many instances of the case are used or created later.

Swift offers another option, however, with associated values. When using AV’s, instead of declaring the value when the declare the enum, we can have a different associated value with each INSTANCE of the enum. Think of Associated Values as stored properties of the enumeration case instance.

enum ServerResponse {
    case result(String, String)
    case failure(String)
}
let success = ServerResponse.result("6:30am", "9:30pm")
let failure = ServerResponse.failure("Server Error")

switch success {
case let .result(sunrise, sunset):
print(“Sunrise is at (sunrise) and Sunset is at (sunset)”)
case let .failure(message):
print(“Sorry, we were unable to fetch data from the server”)
}

48
Q

What is a Structure in Swift, and how is it different from a Class?

A

A structure is a data container which supports many of the same types of data/properties as Classes - Vars, Funcs, Inits.

A couple key differences:

  • Structs get a “free init” in Swift, meaning we can use them without declaring all of their variables values prior to runtime. You do not need to use an explicit Init.
  • Structs are copied in memory rather than being referenced via pointers. Very different implications for memory than Classes.
49
Q

Compare Enums and Generics - how are they similar and different?

A

Generics and Enums both enable us to create new types in swift and pass them around in our code, but otherwise they are quite different.

Generics don’t do anything other than create a ‘I don’t care’ data type. Generics don’t let us store values on that data type, it’s just a very basic implementation of custom types.

Enums, in contrast, not only let us create a new type which can then be used by vars and other properties in classes and structs, but they let us STORE VALUES on that type using conditionals (the switch statements you’ve seen in enums). So an Enum, for example, makes the following possible:

struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}
let threeOfSpades = Card(rank: .three, suit: .spades) //prints "The three of spades"
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

Above, we’re creating a struct and giving it two properties, rank, and suit, which are of TYPE Rank and Suit respectively - these are two types we made with enums. And because we used Enums instead of Generics, we’re actually able to retrieve values from these enums - like “.three” and “.spades” - and use them in our code. We can also retrieve the simpleDescription function from our enum and use it on our new threeOfSpadesDescription property.

50
Q

Using Enum/Struct/Func, how would you create a deck of cards, one card of each suit?

A

Make an enum for Card Rank which has all the card values (ace, queen, three, etc), make an enum for Card Suit which has all the Suits, make a Struct called Card which has a var each for rank and suit, and then write a function (which takes no args and returns an array of type Card) that creates an array of ranks, an array of suits, and use nested for loops to cycle through each rank, and each suit, and append that Card to the Array which will be our card deck.

51
Q

What is a Protocol?

A

A protocol is a blueprint, or a set of rules, that conforming Classes, Structs, and Enums must conform to.

Protocols define rules or requirements, such as funcs and properties, that other classes, structs, and enums then adopt, and provide an actual implementation for. Any class that satisfies the rules of a protocol, is said to conform to that protocol.

52
Q

Let’s say we have a class called Edible, and alternatively, a Protocol called Edible, each with a func eat() within them, what is the difference as far as implementation?

A

Protocols, unlike Classes, do not implement the functions or properties they use, they merely define it.

protcol Edible
{
		func eat() //notice this func does nothing here
{
class Apple: Edible
{
    func eat()
    {
        print("Omnomnom! Eating the apple...")
    } //the class of type Edible actually IMPLEMENTS the function.
}

Note while you don’t implement the functions code body in a protocol, you DO have to specify the arguments and returns.

53
Q

How, syntactically, does a Class or Struct conform to a protocol in its declaration?

A

class Apple: Edible

Very similar to subclass/superclass syntax, we state the data type, name, and then the protocol it adheres to after a colon and a space.

54
Q

Let’s say we have a Class called SimpleClass, which adheres to ExampleProtocol, with var simpleDescription, var anotherProperty, and a func adjust(). We also have our protocol, ExampleProtocol, which only has var simpleDescription, and func adjust().

We then create a var, a, which is of type SimpleClass()

We then create a constant, test, which adheres to ExampleProtocol, and is set equal to a.

What functions and properties can test use without throwing an error?

A

In this type of scenario, the property adhering to the protocol can only access functions/properties THAT ARE PART OF THE PROTOCOL - it cannot use the additional property, anotherProperty, which is part of the class the property we’re creating conforms to.

This is to ensure that the new property can’t accidentally access funcs and properties from the class it belongs to if it needs to conform to a protocol.

55
Q

What is an Extension?

A

Extensions allow you to add new functionality (new properties or funcs) to or edit existing classes, structs, protocols, or enums.

Most importantly, they allow you to add these even if you don’t have access to the source code of a class or other data structure. In this way, they can be very helpful working with 3rd party libraries and SDKs.

It lets you work with and change code written by others, without actually changing the source code.

class Airplane {
    var altitude: Double = 0
    func setAltitude(feet: Double) {
        altitude = feet
    }
}
extension Airplane {
    func setAltitude(meter: Double) {
        altitude = (meter * 3.28084)
    } //this doesn't CHANGE the source code of Airplane, it just lets you do what you want with it.
}

let Boeing747 = Airplane()
Boeing747.setAltitude(feet: 35000)
print(Boeing747.altitude) // prints 35000
Boeing747.setAltitude(meter: 8000)
print(Boeing747.altitude) // prints 26246.72

56
Q

What can Extensions NOT do?

A

Extensions can MODIFY existing things in a struct, class, enum, or protocol, but they cannot ADD new properties or functions. Doing so would fundamentally change the memory allocation needed for the original object.

57
Q

How do we represent errors in Swift?

A

By using any type that adopts the Error protocol.

E.g. enum PrinterError: Error {
case noPaper
case noToner
case printerOnFire
}
58
Q

How do we, syntactically, throw an error? What about for functions?

A

We use throw to throw an error, and use throws to indicate a function that can throw an error.

59
Q

Explain how you use a Do/Catch block to handle an error.

A

Within the Do block, write your code that can throw an error by writing try in front of it.

Inside the catch block, the error is automatically given the name error, unless you specify an explicit name.

do {
    let printerResponse = try print(job: 27, printerName: "Dave's Printer")
    print(printerResponse)
}
catch {
    print(error)
}
60
Q

Explain how you use Do/Catch block to handle multiple possible errors.

A

The syntax is quite similar to an if/else statement, with successive ‘catch’ syntax for each error you want to specify;

do {
    let secondPrinterResponse = try print(job: 1040, printerName: "The worst printer")
    print(secondPrinterResponse)
} catch PrinterError.printerOnFire {
    print("Ill need to extinguish the fire first, sir")
} catch {
    print(error)
}
61
Q

How can we use ‘try?’ to handle errors?

A

You can use try? to convert the result to an optional. If the function throws an error, the specific error is discarded and the returned value is nil. Otherwise, the result is an optional containing the value returned by the function.

let printerSuccess = try? print(job: 1100, printerName: "Dave's Good Printer")
let printerFailure = try? print(job: 1200, printerName: "Printer With No Toner")

print(printerSuccess) // prints “Print Successful”
print(printerFailure) // prints nil

62
Q

You have two primary ways of handling errors, do/catch and try? - why would you use one over the other, and vice versa?

A

Do/Catch blocks are used when you care about the specific error, because you can not only see the error thrown, but also print or do specific actions for specific errors. Try? is a less dense syntax, but it discards the error thrown and simply returns nil. So Try? is good if you don’t care what the error is, just that there is one, whereas Do/Catch is better for specific error situations.

63
Q

What does Defer do?

A

Defer can be used within a function to specify code that should be run last in the function, just before the function returns. The code is executed regardless of whether or not the function throws an error.

Defer lets you write setup and cleanup code next to each other, even though they are run at different times.

var fridgeIsOpen = false
let fridgeContent = ["Milk", "Cheese", "Bread"]
func fridgeContains(_ food: String) -> Bool {
    fridgeIsOpen = true
    defer {
        fridgeIsOpen = false
    }
    let result = fridgeContent.contains(food)
    return result
}
64
Q

What Types can be used with Generics?

A

Functions/Methods, as well as Enums, Structs, and Classes.

65
Q

How do we declare a Generic? How would you declare an ‘ExampleStruct’ of Type ‘Person’?

A

Using <> so for example

struct ExampleStruct {
var personID: Int

]

struct Person {
var name: String
var hometown: String
}