in July of 2010. I implemented much of the basic language structure, with only a few people knowing of its existence. A few other (amazing) people started contributing in earnest late in 2011, and it became a major focus for the Apple Developer Tools group in July 2013. — Chris Lattner
experiences hard-won by many other languages in the field, drawing ideas from Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, and far too many others to list. — Chris Lattner
readonly, cannot be re-assigned constant = 2 // ❌ ERROR !!! var variable = 1 // readwrite, can be re-assigned variable = 2 // OK // Type inference multiple variables var variable1 = 1, variable2 = 2, variable3 = 3 By convention you should prefer to use 'let' over 'var', when possible
(1.0, -2.0) // Compound Type: (Double, Double) let (real, imag) = complex // Decompose let (real, _) = complex // Underscores ignore value // Access by index let real = complex.0 let imag = complex.1 // Name elements let complex = (real: 1.0, imag: -2.0) let real = complex.real
var optionalInt: Int? = 42 optionalInt = nil // to indicate that the value is missing var optionalDouble: Double? // automatically sets to nil // Check if nil optionalDouble == nil optionalDouble != nil
optionalInt: Int? = 42 let definitelyInt = optionalInt! // throws runtime error if nil // Optional binding if let definitelyInt = optionalInt { // runs if optionalInt is not nil and sets definitelyInt: Int }
var assumedInt: Int! // set to nil assumedInt = 42 var implicitInt: Int = assumedInt // do not need an exclamation mark assumedInt = nil implicitInt = assumedInt // ❌ RUNTIME ERROR !!!
// 1 // Increment and Decrement Operator i++; ++i; i--; --i // Compound Assignment Operator i += 1 // i = i + 1 // Logical Operator a || b && c // equivalent to a || (b && c)
b ? 1 /* if true */ : 0 /* if false */) // Nil Coalescing Operator a ?? b // a != nil ? a! : b // Closed Range Operator 0...2 // 0, 1, 2 // Half Open Range Operator 0..<2 // 0, 1
the top of the loop while x > 2 { /* */ } // do-while evaluates its expression at the bottom of the loop do { /* executed at least once */ } while x > 2
and by convention are often omitted {Braces} are always required, even in one statement only bodies1 if temperature > 37 { feverish = true } // OK if (temperature > 37) { feverish = true } // OK if (temperature > 37) feverish = true // ❌ ERROR !!! 1 Do you remember the infamous "goto fail;" Apple's SSL bug ?
func foo(parameter1: Type1, parameter1: Type2) -> ReturnType { /* function body */ } foo(argument1, argument2) // call // Without parameters and return value func bar() -> Void { /* function body */ } func baz() -> () { /* function body */ } func quz() { /* function body */ } quz() // call
of parameter - let is the default and can be omitted // var creates a local mutable copy of parameter - var can't modify given instance passed as value func foo(let costantParameter: Int, var variableParameter: Int) { costantParameter += 1 // ❌ ERROR !!! variableParameter += 2 // OK } // inout allows to modify given instance passed as value func bar(inout parameter: Int) { parameter = 42 } var x = 0 // cannot be declared with 'let' bar(&x) // need the & in the call x // = 42
(Int) -> Int func addOne(n: Int) -> Int { return n + 1 } // Function as parameter func foo(functionParameter: (Int) -> Int) { /* */ } foo(addOne) // Function as return type func bar() -> (Int) -> Int { func addTwo(n: Int) -> Int { return n + 2 } return addTwo }
parameters as // an equivalent function that takes a single parameter and returns a function func addTwoInts(a: Int, b: Int) -> Int { return a + b } func addTwoIntsCurried (a: Int) -> (Int) -> Int { func addTheOtherInt(b: Int) -> Int { return a + b } return addTheOtherInt } // equivalent to: func addTwoIntsCurried (a: Int)(b: Int) -> Int { return a + b } addTwoInts(1, 2) // = 3 addTwoIntsCurried(1)(2) // = 3
can apply the @autoclosure attribute to a function type that // has a parameter type of () and that returns the type of an expression func simpleAssert(condition: () -> Bool, message: String) { if !condition() { println(message) } } // An autoclosure function captures an implicit closure over the specified expression, // instead of the expression itself. func simpleAssert(condition: @autoclosure () -> Bool, message: String) { if !condition() { println(message) } } simpleAssert(3 % 2 == 0, "3 isn't an even number.") // By taking the right side of the expression as an auto-closure, // Swift provides proper lazy evaluation of that subexpression func &&(lhs: BooleanType, rhs: @autoclosure () -> BooleanType) -> Bool { return lhs.boolValue ? rhs().boolValue : false } 2 see Swift Blog Post: Building assert() in Swift
not capture any values ▸ Nested functions: named closures / capture values from enclosing function ▸ Closure expressions: unnamed closures / capture values from their surrounding context
Enumerations & Structures are passed by Value ▸ Classes are passed by Reference Enumerations & Structures are always copied when they are passed around in the code, and do not use reference counting.
CLASSES: ▸ Define properties, methods and subscripts ▸ Define initializers to set up their initial state ▸ Be extended to expand their functionality ▸ Conform to protocols to provide standard functionality
enables one class to inherit from another. ▸ Type casting enables to check the type of an object at runtime. ▸ Deinitializers enable an object to free up any resources. ▸ Reference counting allows more than one reference to an object.
OF ITEMS enum CellState { case Alive case Dead case Error } let state1 = CellState.Alive; let state2 : CellState = .Dead // if known type, can drop enumeration name switch state1 { case .Alive: /* ... */ case .Dead: /* ... */ default: /* ... */ }
CellState { case Alive case Dead case Error(Int) // associated value can also be a tuple of values } let errorState = CellState.Error(-1); // extract associated value as constant or variable switch errorState { case .Alive: /* ... */ case .Dead: /* ... */ case .Error(let errorCode): // == case let .Error(errorCode)): /* use errorCode */ }
{ case None case Some(Int) } let maybeInt: OptionalInt = .None // let maybeInt: Int? = nil let maybeInt: OptionalInt = .Some(42) // let maybeInt: Int? = 42 3 indeed the Swift Library's Optional use Generics (see below)
CellState { case Alive = 1 case Dead = 2 case Error = 3 } enum CellState: Int { // Specify the Item Raw Value Type case Alive = 1, Dead, Error // Int auto-increment } let stateValue = CellState.Error.rawValue // 3 let aliveState: CellState? = CellState(rawValue: 1) // CellState.Alive
// Structures are value types struct CellPoint { var x = 0.0 var y = 0.0 } // Structures are always copied when they are passed around var a = CellPoint(x: 1.0, y: 2.0); var b = a; b.x = 3.0; a.x // 1.0 - a not changed
= "" // == var emptyString = String() emptyString.isEmpty // true let constString = "Hello" // Character Declaration var character: Character = "p" for character in "Hello" { // "H", "e", "l", "l", "o" } // Declare a String as var in order to modify it var growString = "a"; growString += "b"; growString.append("c") countElements(growString) // 3
Array<Int>() var emptyArray : [Int] = [] var array = [Int](count: 2, repeatedValue: 0) var array = [25, 20, 16] // Array Access: subscript out of bounds generate crash array[1] // 20 array[1000] // ❌ RUNTIME ERROR !!! array.count // 3 array.isEmpty // false // Array Iteration for value in array { /* use value */ } for (index, value) in enumerate(array) { /* use index and value */ }
// Classes are reference types class Person { var name: String? var age: Int = 0 } // Class reference (not object) are copied when they are passed around var giuseppe = Person() let joseph = giuseppe joseph.name = "Joseph" giuseppe.name // "Joseph" // Compare references using === and !== giuseppe === joseph // true
// constant stored property var position: CellPoint? // variable stored property var score: Int = 10 // variable stored property with default value lazy var spa = Spa() // lazy stored property (only var) // lazy: a property whose initial value is not calculated until the first time it is used } struct CellPoint { var x = 0.0 // variable stored property with default value var y = 0.0 // variable stored property with default value } // Enumerations do not have instance stored properties
available only for Enumerations and Structures struct Path { // You must always give stored type properties a default value static var maxLength = 1000 } // Computed Type Properties: available for Enumerations, Structures and Classes struct Path { static var maxLength: Int { return Int.max / 2 } /* Structures use 'static' keyword */ } class Cell { class var maxNum: Int { return Int.max / 5 } /* Classes use 'class' keyword */ } }
willSet(newDurationValue) { /* ... */ } didSet(oldDurationValue) { /* ... */ } } // Using default parameter names 'newValue' and 'oldValue' var cost: Double { willSet { /* use newValue */ } didSet { /* use oldValue */ } } } 4 You can add property observers to any stored properties you define, apart from lazy stored properties. You can also add property observers to any inherited property (whether stored or computed) by overriding the property within a subclass.
// type method class func dispatchAll() { /* ... */ } // use 'static' for Structures // instance methos func moveTo(destination: CellPoint, withSteps: Int) { // first argument treated as local name (require explicit #) // rest of arguments treated as external and local name (have implicit #) // to omit implicit external name requirement use an undescore _ } } var cell = Cell() cell.moveTo(center, withSteps: 10) cell.moveTo(center, 10) // ❌ ERROR !!! Cell.dispatchAll()
state, must be marked as 'mutating' struct CellPoint { var x = 0.0, y = 0.0 mutating func moveByX(deltaX: Double, y deltaY: Double) { x += deltaX y += deltaY } // equivalent assigning to self mutating func moveByX(deltaX: Double, y deltaY: Double) { self = Point(x: x + deltaX, y: y + deltaY) } } var point = CellPoint(x: 3.0, y: 4.0) point.moveByX(1.0, y: 2.0)
be subclassed final class Car : Vehicle { /* ... */ } class Jeep : Car // ❌ ERROR !!! class Bicycle : Vehicle { // final property cannot be overridden final var chainLength: Double // final method cannot be overridden final func pedal() { /* ... */ } }
// Classes and Structures must set all of their stored properties // to an appropriate initial value by the time an instance is created let model: String // stored properties must be initialized in the init let wheels = 4 // stored properties with default property value are initialized before the init //Initializers are declared with 'init' keyword init() { model = "Supercar" } } // Initializers are called to create a new instance of a particular type with Type() syntax let car = Car() car.model // "Supercar"
You can set the value of a constant property at any point during initialization // An automatic external name (same as the local name) is provided for every parameter in an initializer init(model: String) { // equivalent to: init(model model: String) self.model = model // use self. to distinguish properties from parameters } // alternatively init (fromModel model: String) { /* ... */} // override the automatic external init (_ model: String) { /* ... */} // omit automatic external name using an underscore _ } // Initializers are called with external parameters let car = Car(model: "Golf") car.model // "Golf"
{ // For classes only: failable initializer can trigger a failure // only after all stored properties have been set let wheels: Int! // set to nil by default init?(wheels: Int) { if weels > 4 { return nil } self.wheels = wheels } } var car: Car? = Car(wheels: 10) // nil if let realCar = Car(wheels: 4) { println("The car has \(car.wheels) wheels") }
with no superclass or structure // if these conditions are all valid: // 1) all properties have default values // 2) the type does not provide at least one initializer itself class Car { var model = "Supercar" let wheels = 4 } let car = Car() car.model // "Supercar"
a memberwise initializer // if they do not define any of their own custom initializers struct Wheel { var radius = 0.0 var thickness = 0.0 } let Wheel = Wheel(radius: 10.0, thickness: 1.0)
var model: String init (model: String) { /* ... */} // Designated initializers // are the primary initializers for a class convenience init () { /* ... */} // Convenience initializers // are secondary, supporting initializers for a class } var golf = Car(model: "Golf") var supercar = Car()
initializer must call a designated initializer from its immediate superclass. // Rule 2: A convenience initializer must call another initializer from the same class. // Rule 3: A convenience initializer must ultimately call a designated initializer. class Vehicle { var wheels: Int init (wheels: Int) { self.wheels = wheels } } class Car: Vehicle { var model: String init (model: String) { super.init(wheels: 4); self.model = model } convenience init () { self.init(model: "Supercar") } }
Phase // each stored property is assigned an initial value by the class that introduced it. // The Second Phase // each class is given the opportunity to customize its stored properties further // before the new instance is considered ready for use. }
1 // A designated initializer must ensure that all of the properties introduced by its class // are initialized before it delegates up to a superclass initializer. // Safety check 2 // A designated initializer must delegate up to a superclass initializer // before assigning a value to an inherited property. // Safety check 3 // A convenience initializer must delegate to another initializer // before assigning a value to any property (including properties defined by the same class). // Safety check 4 // An initializer cannot call any instance methods, read the values of any instance properties, // or refer to self as a value until after the first phase of initialization is complete.” }
// Assuming that you provide default values for any new properties you introduce in a subclass var model = "Supercar" // Rule 1 // If your subclass doesn’t define any designated initializers, // then it automatically inherits all of its superclass designated initializers. // Rule 2 // If your subclass provides an implementation of all of its superclass designated initializers // (either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition) // then it automatically inherits all of the superclass convenience initializers. } let car = Car() // car.model == "Supercar"
{ /* ... */ } } class Car: Vehicle { // You do not write the override modifier // when overriding a required designated initializer required init () { super.init(); } }
is called immediately // before a class instance is deallocated deinit { /* free any external resources */ } } var car: Car? = Car() car = nil // as a side effect call deinit
up the memory used by class instances // when those instances are no longer needed (reference count == 0) class Car { /* ... */ } var reference1: Car? var reference2: Car? var reference3: Car? reference1 = Car() // reference count == 1 reference2 = reference1 // reference count == 2 reference3 = reference1 // reference count == 3 reference1 = nil // reference count == 2 reference2 = nil // reference count == 1 reference3 = nil // reference count == 0 // no more reference to Car object => ARC dealloc the object
{ var tenant: Person } class Person { var car: Car } car.person = person person.car = car // weak and unowned resolve strong reference cycles between Class Instances
whenever it is valid for that reference to become nil at some point during its lifetime class Person { let name: String init(name: String) { self.name = name } var car: Car? deinit { println("\(name) is being deinitialized") } } class Car { let wheels: Int init(wheels: Int) { self.wheels = wheels } weak var tenant: Person? deinit { println("Car #\(wheels) is being deinitialized") } }
when you know that the reference will never be nil once it has been set during initialization. class Country { let name: String let capitalCity: City! init(name: String, capitalName: String) { self.name = name self.capitalCity = City(name: capitalName, country: self) } } class City { let name: String unowned let country: Country init(name: String, country: Country) { self.name = name self.country = country } }
capture the value at the time of closure's definition var i = 1 var returnWithCaptureList = { [i] in i } // captures value of i var returnWithoutCaptureList = { i } // do not capture value of i i = 2 returnWithCaptureList() // 1 returnWithoutCaptureList() // 2 class MyClass { // Use capture lists to create weak or unowned references lazy var someClosure1: () -> String = { [unowned self] () -> String in "closure body" } // can infer types of closure parameters lazy var someClosure2: () -> String = { [unowned self] in "closure body" } }
{ /* ... */ } class Bicycle: Vehicle { /* ... */ } let vehicles = [Car(), Bicycle()] // Type checking let firstVehicle = vehicles[0] firstVehicle is Car // true firstVehicle is Bicycle // false // Type downcasting let firstCar = firstVehicle as? Car // firstCar: Car? let firstCar = firstVehicle as Car // firstCar: Car let firstBicycle = firstVehicle as? Bicycle // nil: Car? let firstBicycle = firstVehicle as Bicycle // ❌ RUNTIME ERROR !!!
switch thing { case 0 as Int: /* ... */ // thing is 0: Int case 0 as Double: /* ... */ // thing is 0.0: Double case let someInt as Int: /* ... */ case is Double: /* ... */ default: /* ... */ } }
{ // struct ⽹ class Note { // nested class ⽹ enum Pitch: Int { // nested enumeration case A = 1, B, C, D, E, F, G } var pitch: Pitch = .C var length: Double = 0.0 } var notes: [Note] } Song.Note.Pitch.C.rawValue // 3
unit of code distribution (a framework or an application) A source file is a single Swift source code file within a module (can contain definitions for multiple types, functions, and so on)
be used within any source file from their defining module, // and also in a source file from another module that imports the defining module internal // enables entities to be used within any source file from their defining module, // but not in any source file outside of that module private // restricts the use of an entity to its own defining source file.
class SomePublicClass { public var somePublicProperty var someInternalProperty // default is internal private func somePrivateMethod() {} } // internal class class SomeInternalClass { var someInternalProperty // default is internal private func somePrivateMethod() {} } private class SomePrivateClass { var somePrivateProperty // everything is private! func somePrivateMethod() {} }
// Protocols define a blueprint of requirements that suit a functionality var instanceProperty: Type { get set } // Protocols can require instance properties (stored or computed) class var typeProperty: Type { get set } // Protocols can require type properties (stored or computed) // Always use 'class', even if later used by value type as 'static' func someMethod() // Protocols can require instance methods mutating func someMutatingMethod() // Protocols can require instance mutanting methods class func someTypeMethod() // Protocols can require type methods init() // Protocols can require initializers }
TYPE // Conforming to a protocol class SomeClass: SomeProtocol { // init requirements have 'required' modifier required init() { /* ... */ } // ('required' not needed if class is final) // Other requirements do not have 'required' modifier var someReadWriteProperty: Type ... } // Protocol used as type let thing: SomeProtocol = SomeClass() let things: [SomeProtocol] = [SomeClass(), SomeClass()]
type let instance: Any = { (x: Int) in x } let closure: Int -> Int = instance as Int -> Int // AnyObject: any object of a class type let instance: AnyObject = Car() let car: Car = x as Car let cars: [AnyObject] = [Car(), Car(), Car()] // see NSArray for car in cars as [Car] { /* use car: Car */ }
be compared // for value equality using operators '==' and '!=' protocol Equatable { func ==(lhs: Self, rhs: Self) -> Bool } // Instances of conforming types provide an integer 'hashValue' // and can be used as Dictionary keys protocol Hashable : Equatable { var hashValue: Int { get } }
and expresses its intent in the abstract ▸ Much of the Swift Library is built with generics (Array, Dictionary) ▸ Compiler can optimize by creating specific versions for some cases ▸ Type information is available at runtime
array.append(item) } var someArray = [1] append(&someArray, 2) // T: SomeClass -> T must be subclass of SomeClass // T: SomeProtocol -> T must conform to SomeProtocol func isEqual<T: Equatable>(a: T, b: T) -> Bool { return a == b }
the Associated Type func operate(item: ItemType) // a placeholder name to a type used in a protocol } class SomeClass: SomeProtocol { typealias ItemType = Int // Specify the actual Associated Type func operate(item: Int) { /* ... */ } } class SomeClass: SomeProtocol { // typealias ItemType = Int // Infer the actual Associated Type func operate(item: Int) { /* ... */ } }
objects with implicit root class ‘SwiftObject’ ▸ Just like C++, Swift methods are listed in a vtable unless marked as @objc or :NSObject* ▸ Swift's runtime and libraries are not (yet) included in the OS so must be included in each app
passion of mine, to make programming more interactive and approachable. The Xcode and LLDB teams have done a phenomenal job turning crazy ideas into something truly great. Playgrounds were heavily influenced by Bret Victor's ideas, by Light Table and by many other interactive systems. — Chris Lattner
available in Objective-C (no Generics, no...) ▸ Subclassing Swift classes not allowed in Objective-C ▸ Mark Swift Classes as Objective-C compatible with @objc ▸ Use automatic generated Swift module header in MyApp-Swift.h
your own dragons if you want, but your speculation is just that: speculation. We literally have not even discussed this yet, because we have a ton of work to do [...] You can imagine that many of us want it to be open source and part of llvm, but the discussion hasn't happened yet, and won't for some time. — Chris Lattner @ llvmdev
6.1 ] ▸ Compiler attributes and Preprocessor ▸ Class Variables, Exceptions, KVO, KVC and Reflection6 6 Though it’s not documented in the Swift Standard Library — and is subject to change — Swift has a reflection API: let mirror = reflect(instance) // see Reflectable Protocol
Furrow ▸ Swift Enums, Pattern Matching, and Generics by Austin Zheng ▸ Swift and Objective-C: Best Friends Forever? by Jonathan Blocksom ▸ Swift for JavaScript Developers by JP Simard ▸ Swift for Rubyists by JP Simard
An Absolute Beginner’s Guide to Swift by Amit Bijlani ▸ Swift Tutorial: A Quick Start by Ray Wenderlich ▸ Learn Swift Build Your First iOS Game by Stan Idesis ▸ Swift Essential Training by Simon Allardice