Swift Rocks! Anton Mironov Software Engineer at 1
Operators
infix operator + { associativity left precedence 140 }
func +(lhs: Int, rhs: Int) -> Int
12
Auto casting can be EvilNSEventModifierFlags modifierFlags = NSApp.currentEvent.modifierFlags;
BOOL isControlKeyPressed = modifierFlags & NSControlKeyMask;
if (isControlKeyPressed) { NSLog(@"Control pressed"); } else { NSLog(@"Control NOT pressed"); }
15
Branchingswitch numberOfApples { case 0: return "none" case 6...10: return "just right" case 42, -1: return "let me see" case let value where (1 == value % 2): return "that's odd" default: return "this is unacceptable" } 18
Collections: Dictionary
let dictionaryOfNamesByDigit = [ 5: "five", 4: "four", 3: "three", 2: "two", 1: "one" ]
21
Cycles: Enumeration
let arrayOfInts = [5, 4, 3, 2, 1] for value in arrayOfInts { print("\(value)") }
25
Swift: Optionals
if nil != person { return "Hello \(person!)" } else { return "Hello to nobody" }
28
Swift: Optionals
if let nonNullPerson = person { return "Hello \(nonNullPerson)" } else { return "Hello to nobody" }
29
Functions: named arguments
func buildMessageForPerson( person: String, role: String) -> String { return "\(name), I am your \(role)" }
let message = buildMessageForPerson("Luke", role: "father" )
32
Functions: default valuesfunc buildMessageForPerson( person: String = "Luke", role: String) -> String { return "\(person), I am your \(role)" }
let message = buildMessageForPerson( role: "father" )
33
Functions: multiple returnfunc divide( a: Int, _ b: Int ) -> (result: Int, modulo: Int) { return (a / b, a % b) }
let result = divide(11, 4).result let modulo = divide(11, 4).modulo
34
Functions as arguments Simple Example
func add(a: Int, b: Int) -> Int { return a + b } func mul(a: Int, b: Int) -> Int { return a * b }
func runMathOp(a: Int, _ b: Int, op: (Int, Int) -> Int ) -> Int { return op(a, b) }
let value1 = runMathOp(4, 3, op: add) let value2 = runMathOp(4, 3, op: mul)
36
Functions as arguments Simple Example
func runMathOp(a: Int, _ b: Int, op: (Int, Int) -> Int ) -> Int { return op(a, b) }
let value1 = runMathOp(4, 3, op: +) let value2 = runMathOp(4, 3, op: -)
37
Imperative Stylelet names = ["Luke", "Chuwy", "Baker"] var messages = [String]()
for name in names { let message = buildMessageForPerson(name, "father") messages.append(message) }
print("\(messages)")
39
Functional Stylelet names = ["Luke", "Chuwy", "Baker"] let messages = names.map { buildMessageForPerson($0, "father") }
print("\(messages)")
40
Closuresfunc buildOperation(multiplier: Int ) -> (Int -> Int) { func multiply(value: Int) -> Int { return value * multiplier }
return multiply }
let operation = buildOperation(3) let value = operation(4)
41
Type System Classification Criteria: Parameters Passing and Ownership• By Value let a = 3
• By Sharing (by reference to shared object) let userDefaults = NSUserDefaults.standardUserDefaults()
• By Reference let operation = myFunction let c = operation(a, b)
44
Type System Classification Criteria: Access Control
• Public - visible for importers
• Internal (default) - visible within module
• Private - visible within file
46
Classesclass Transport { let name: String private var velocity: Double = 0.0 init(name: String) { self.name = name }
} 53
Classesclass Transport { let name: String private var velocity: Double = 0.0 init(name: String) { self.name = name } func beep() { print("Beep!") } } 54
Structuresstruct Point2D { var x: Double var y: Double
init(x: Double, y: Double) { self.x = x self.y = y } }
63
Structuresvar point1 = Point2D(x: 1.0, y: 2.0) var point2 = point1 point1.x = 3.0
// (point1.x != point2.x)
64
Structuresstruct Point2D { var x: Double var y: Double … mutating func multiply(
mult: Double) { self.x *= mult self.y *= mult } }
66
Structures are everywhere• Int, Bool, UInt64, Float, Double, …
• String
• Array, Set, Dictionary
• …
67
Enumsenum TokenStatus: String { case None = "none" case Valid = "valid" case Invalid = "invalid" case Expired = "expired"
var shouldRefetch: Bool { return .Valid == self } }
68
Enums (Unions)enum FileSystemError: ErrorType { case InvalidURL(NSURL) case InvalidPermissions case UnknownErrorCode(Int) }
69
Enums (Unions)switch fileSystemError { case .InvalidURL(let URL): print("Invalid URL \(URL)") case .InvalidPermissions: print("Invalid permissions") case .UnknownErrorCode(let code) where code == -150: print("I've seen this error somewhere") case .UnknownErrorCode(let code): print("Something gone very wrong \(code)") }
70
Protocolsprotocol Drawable { var boundingRect: NSRect { get } func draw() }
struct Polygon: Drawable { var points = [NSPoint]() //MARK: Drawable var boundingRect: NSRect? { ... } func draw() { ... } } 71
Generic Functionsfunc min<T: Comparable>( lhs: T, _ rhs: T ) -> T { return lhs < rhs ? lhs : rhs }
72