Stanford Swift Flashcards
Give a good example of unwrapping
// NB ** GOOD EXPLANATION OF UNWRAPPING *** unwrap this as the result is an optional in the brain (ie the MODEL). The code below basically means if the result is determined, then you will let the displayValue equal the result (ie the brain.result, but we can’t use this direclty as this could be an optional!) .
if let result = brain.result { displayValue = result }
What is an unary operations?
What is a binary operation?
Unary Operation: eg square root. Performs an operation on one operand (ie the number being operation on)
Binary Operation: eg multiplication. Performs operation on multiple operations (ie multiplying two numbers together)
What is optional defaulting?
eg 1
// Optional defaulting works as follows. If the display is blank you want a space
let s: String? = ... // might be nil if s != nil { display.text = s } else { display.text = " " }
// can be expressed as
display.text = s ?? “ !
What are tuples?
eg 1 (least used)
// A tuple is a grouping of values. You can use it anywhere you’re using a type.
let x: (String, Int, Double) = ("hello", 5, 0.85) // the type of x is "a tuple".
let (word, number, value) = x // this names the tuple elements when accessing the tuple
print(word) // prints hello
print(number) // prints 5
print(value) // prints 0.85
What are tuples?
eg 2 (most used)
// the tuples elements can be named when the tuple is declared (this is strongly preferred)…
let x (w: String, i: Int, v: Double) = ("hello", 5, 0.85) print(x.w) // prints hello print(x.i) // prints 5 print(x.v) // prints 0.85
Explain tuples as return values
You can use tuples to return multiple values from a function or method.
func getSize() -> (weight: Double, height: Double) { return (250, 80) }
let x = getSize() print("weight is \(x.weight)") // weight is 250
// …or
print(“height is (getSize().height)”) // height is 80
What is a Range in Swift?
//A range in Swift is just two end points
// A range can represent things like a selection in some text or a portion of an Array.
// Range is generic (eg Range ), but T is restricted (eg comparable - the start index has to be less than the end index). This is sort of a pseudo-representation of Range…it’s a bit more complicated. You can have a range of ints, floats, and even strings.
struct Range {
var startIndex: T
var endIndex: T
}
// Syntax for created a Range ..< // exclusive of the upper bound or ... (inclusive of both bounds)
What is a CountableRange
A CountableRange contains consecutive values which can be iterated over or indexed into
Give an example of creating a Range
let array = ["a", "b", "c", "d"] let a = array[2...3] // a will be a slice of the array c and d let b = array[2..<3] // will be a slice of the array c
CountableRange is enumeratable with ‘for in’
Give an example of this
// Count through/enumerate through the sequence
for (i = 0; i < 20; i++) // loop in C-like language
for i in 0..<20 {
}
you can ‘for in’ through different sequences - ie countableRange, arrays, dictionaries
Do floating point numbers stride by Int?
No, they stride by floating points value.
So 0.5…15.25 is just a range, not a CountableRange (which is needed for ‘for in’)
There’s a global function that will create a countable range from floating point values
for i in stride(from:0.5, through: 15.25, by: 0.3) {
}
Return type of stride is ClosedCountableRange
What are the four data structures in Swift?
Classes, Structures, Enumerations, and Protocols. Only difference is a Class can specify a Superclass.
eg in Calculator // declaration syntax class ViewController { } struct calculator brain { } enum operation { } // Similarities They can all have properties and functions, but there can't be any stored properties in an enum. Enums keep any data it has in associated values. It can have computed properties however. Structs and Classes have initialisers apart from enums, as you just say the case you want. // Differences Classes are the only ones that have inheritance. nb Structs and Enums are Value types, and Classes are Reference types
What is a value type? (eg struct and enum)
A value type is…
- Copied when passed as an argument to a function
- Copied when assigned to a difference variable
- Immutable if assigned to a variable with let (function parameters are let). You must note any func that can mutate a struct/enum with the keyword mutating
What is a reference type? (eg class)
A reference class gets stored in the heap with a pointer to it
- Stored in the heap and reference counted (automatically)
- Constant pointers to a class (let) still can mutate by calling methods and changed properties (the pointer can’t be changed but what it points to can).
- When passed as an argument, does not make a copy (just passing a pointer to some instance).
When would you use a class, vs struc or enum
ie reference types vs value types
Use of enum is situational - any time you have a type of data with discrete values.
Briefly describe Method syntax
Method syntax:
All parameters to all functions have an internal name and an external name. The internal name is the name of the local variable you use inside the method
// eg ‘first’, ‘second’ are internal names - note “” “” is for highlighting
func foo(externalFirst ""first"": Int, externalSecond second: Double) { var sum = 0.0 for _ in 0..
What happens if you put just one parameter name when writing a method?
If you put just one parameter name when writing a method, it will be both the external and internal name
func foo(first: Int, second: Double) { var sum = 0.0 for _ in 0..
How do you stop methods/properties/classes from beeing overridden?
To stop methods/properties/classes from beeing overridden use ‘final’
eg override func …
final func
What are instance methods/vars
Instance methods/vars that are being sent to an instance of a class, struct, or enum …in other ones ‘one of them’ like a double 15.5 ..and then you send it messages
Explain methods and types
Types (eg the type string, the type double, the type calculatorbrain) can also have methods and computed vars. To add a method to a type you put ‘static’ in front of the declaration
eg
‘static func …’ means this is a function on the type, not an instance of the type
// eg - the stuct Double has a number of vars and funcs on its type. These are not methods or vars you access on an instance of a Double (eg on 53.2). Instead you access them by referencing the Double type itself
static func abs(d: Double) -> Double { if d < 0 { return -d } else { return d } }
static var pi: Double { return 3.14 }
let d = Double.pi // returns 3.14 let d = Double.abs(-324.44) //returns 324.44
// Note; pi is a computed var is a computer var on the struc Double. abs takes a Double value and returns the absolute value of it eg -5 to 5
// Also note; let x: Double = 23.85 let e = x.pi // YOU CAN'T DO THIS because pi is not an instance variable...x (ie x has been been made and instance on the double). Here you are trying to send pi to an instance (23.85) , rather than the type (Double), so it won't work
What is a property observer?
A property observer is a little bit of code that executes when your property changes. Use it in the controller or the view.
// You can observe changes to any property with willSet and didSet
var someStoredProperty: Int = 42 {
willSet { newValue is the new value }
didSet { oldValue is the old value }
}
override var inheritedProperty: String {
willSet { newValue is the new value }
didSet { oldValue is the old value }
}
var operations: Dictionary = [ … ] {
willSet { will be executed if an operation is
added/removed }
didSet { will be executed if an operation is
added/removed }
}
Properties; what is lazy initialisation?
A lazy property does not get initialised until someone accesses it. You can allocate an object, execute a closure, or call a method if you want.
lazy var brain = CalculatorBrain() // nice if CalculatorBrain uses a lot of resources
lazy var someProperty: Type = { // construct the value of someProperty here return } ()
lazy var myProperty = self.initialiseMyPropterty()
What are the two ways of writing arrays
var a = Array() ...is the sames as
var a = String
// NB - an array is sa sequence, just like a CountableRange is
// reduce an entire array to a single value. This means it takes an element from the array and the answer so far and adds them
reduce(initial: U, combine: (U, T) -> U) -> U
let sum: Int = [1, 2, 3].reduce(0) { $0 + $1 } // adds up the numbers in the array let sum2 = [1, 2, 3, 4].reduce(0, +) // same thing because + is just a function in Swift. we can do this because + is just a function that takes double doubles either side and returns a double (or Ints, Strings, etc. )
print(sum) // 6
print(sum2) // 10
What are the two ways of writing arrays
var a = Array() ...is the sames as
var a = String
// NB - an array is sa sequence, just like a CountableRange is
// reduce an entire array to a single value. This means it takes an element from the array and the answer so far and adds them
reduce(initial: U, combine: (U, T) -> U) -> U
let sum: Int = [1, 2, 3].reduce(0) { $0 + $1 } // adds up the numbers in the array let sum2 = [1, 2, 3, 4].reduce(0, +) // same thing because + is just a function in Swift
print(sum) // 6
print(sum2) // 10
Describe some interesting Array methods which take closures.
Methods can take functions as arguments: Filter: // The function passed as the argument returns false if an element is undesirable
filter(includeElement: (T) -> Bool) -> [T] let bigNumbers = [2, 47, 118, 5, 9].filter({ $0 > 20 }) // bigNumbers = [47, 118]
Map: // Transform the type map(transform: (T) -> U) -> [U] let stringified: [String] = [1, 2, 3].map { String($0) } // ["1", "2", "3"]
Reduce:
// Reduce an entire array to a single value eg add
reduce(initial: U, combine: (U, T) -> U) -> U
let sum: Int = [1, 2, 3].reduce(0) { $0 + $1 }
// adds numbers in array
let sum = [1, 2, 3,].reduce(0, +) // same thing because + is just a function in Swift
What is a Dictionary’s syntax?
// Dictionary syntax:
var pac12teamRankings = Dictionary
// is the same as
var pac12teamRankings = String:Int
var pac12teamRankings = ["King's": 1, "USC": 11] let ranking = pac12teamRankings["Ohio State"] // ranking is an Int (would be nil). When we use [ ] to get something out of a dictionary it returns an optional of our Value type. ie optional Int. This would be nil as there is no Ohio State in the dictionary
pac12teamRankings[“London”] = 12
Is a Dictionary a collection? Can it be sequenced / enumerated?
// Yes a Dictionary is a collection. It be sequenced / enumerated
// You can use ‘for in’ on it. Use a tuple with for-in to enumerate a dictionary
for (key, value) in pac12teamRankings {
print(“Team (key) is ranked number (value)”)
}
When do you use a struct and when do you use a class?
Remember; the main difference is that structs are value types and classes are reference types.
When you make a copy of a value type (ie class), it copies all the data from the thing you are copying into the new variable. They are 2 separate things and changing one does not affect the other
When you make a copy of a reference type, the new variable refers to the same memory location as the thing you are copying. This means that changing one will change the other since they both refer to the same memory location
For representing a stateful complex entity, a class is awesome. But for values that are simply a measurement or bits of related data, a struct makes more sense so that you can easily copy them around and calculate with them or modify the values without fear of side effects.
***CLASS*** class SomeClass { var name: String init(name: String) { self.name = name } }
var aClass = SomeClass(name: "Bob") var bClass = aClass // aClass and bClass now reference the same instance! bClass.name = "Sue"
println(aClass.name) // “Sue”
println(bClass.name) // “Sue”
****STRUCT*** struct SomeStruct { var name: String init(name: String) { self.name = name } }
var aStruct = SomeStruct(name: "Bob") var bStruct = aStruct // aStruct and bStruct are two structs with the same value! bStruct.name = "Sue"
println(aStruct.name) // “Bob”
println(bStruct.name) // “Sue”
What is a memberwise initializer?
Only available in Structs. You get a ready-made initializer for all the stored properties that don’t have default values.
This means that the Struct can operate when the properties have no default values. And also, there is no initializer implement.
This is super handy, but there are several gotchas. eg - the automatic memberwise initializer argument lists order mirrors that of the stored property list. Be careful, because when re-ordering structure properties (eg reordering them in alphabetical order), you might break instance initialization. Also memberwise initializers only provide parameters for stored properties without default values (eg error if you ‘let nominalBurnTime: Int = 180). To Fix: If the main struct definition doesn’t include any initializers, Swift will still automatically generate the default memberwise initializer. Then you can add your custom ones via extensions to get the best of both worlds.
// struct RocketStageConfiguration { let propellantMass: Double let liquidOxygenMass: Double let nominalBurnTime: Int }
let stageOneConfiguration = RocketStageConfiguration(propellantMass: 119.1, liquidOxygenMass: 276.0, nominalBurnTime: 180)