-
Three new doc comment fields, namely
- keyword:,- recommended:and- recommendedover:, allow Swift users to cooperate with code completion engine to deliver more effective code completion results. The- keyword:field specifies concepts that are not fully manifested in declaration names.- recommended:indicates other declarations are preferred to the one decorated; to the contrary,- recommendedover:indicates the decorated declaration is preferred to those declarations whose names are specified. -
Designated class initializers declared as failable or throwing may now return nil or throw an error, respectively, before the object has been fully initialized. For example:
class Widget : Gadget { let complexity: Int init(complexity: Int, elegance: Int) throws { if complexity > 3 { throw WidgetError.TooComplex } self.complexity = complexity try super.init(elegance: elegance) } }
-
All slice types now have
removeFirst()andremoveLast()methods. -
ArraySlice.removeFirst()now preserves element indices. -
Global
anyGenerator()functions have been changed into initializers onAnyGenerator, making the API more intuitive and idiomatic. -
Closures appearing inside generic types and generic methods can now be converted to C function pointers as long as no generic type parameters are referenced in the closure's argument list or body. A conversion of a closure that references generic type parameters now produces a diagnostic instead of crashing.
(rdar://problem/22204968)
-
Anonymously-typed members of C structs and unions can now be accessed from Swift. For example, given the following struct 'Pie', the 'crust' and 'filling' members are now imported:
struct Pie { struct { bool crispy; } crust; union { int fruit; } filling; }
Since Swift does not support anonymous structs, these fields are imported as properties named
crustandfillinghaving nested types namedPie.__Unnamed_crustandPie.__Unnamed_filling.(rdar://problem/21683348)
Changes between Xcode 6.1 (Swift 1.1) through Xcode 7.1
(Swift 2.1) have been lost. Contributions to rectify this would be
welcome.
-
HeapBuffer<Value,Element>,HeapBufferStorage<Value,Element>, andOnHeap<Value>were never really useful, because their APIs were insufficiently public. They have been replaced with a single class,ManagedBuffer<Value,Element>. See also the new functionisUniquelyReferenced(x)which is often useful in conjunction withManagedBuffer. -
The
Characterenum has been turned into a struct, to avoid exposing its internal implementation details. -
The
countElementsfunction has been renamedcount, for better consistency with our naming conventions. -
Mixed-sign addition and subtraction operations, that were unintentionally allowed in previous versions, now cause a compilation error.
-
OS X apps can now apply the
@NSApplicationMainattribute to their app delegate class in order to generate an implicitmainfor the app. This works like the@UIApplicationMainattribute for iOS apps. -
Objective-C
initand factory methods are now imported as failable initializers when they can returnnil. In the absence of information about a potentially-nilresult, an Objective-Cinitor factory method will be imported asinit!.As part of this change, factory methods that have NSError** parameters, such as
+[NSString stringWithContentsOfFile:encoding:error:], will now be imported as (failable) initializers, e.g.,init?(contentsOfFile path: String, encoding: NSStringEncoding, error: NSErrorPointer)
-
Nested classes explicitly marked
@objcwill now properly be included in a target's generated header as long as the containing context is also (implicitly or explicitly)@objc. Nested classes not explicitly marked@objcwill never be printed in the generated header, even if they extend an Objective-C class. -
All of the
*LiteralConvertibleprotocols, as well asStringInterpolationConvertible, now use initializers for their requirements rather than static methods starting withconvertFrom. For example,IntegerLiteralConvertiblenow has the following initializer requirement:init(integerLiteral value: IntegerLiteralType)
Any type that previously conformed to one of these protocols will need to replace its
convertFromXXXstatic methods with the corresponding initializer.
-
Initializers can now fail by returning
nil. A failable initializer is declared withinit?(to return an explicit optional) orinit!(to return an implicitly-unwrapped optional). For example, you could implementString.toIntas a failable initializer ofIntlike this:extension Int { init?(fromString: String) { if let i = fromString.toInt() { // Initialize self = i } else { // Discard self and return 'nil'. return nil } } }
The result of constructing a value using a failable initializer then becomes optional:
if let twentytwo = Int(fromString: "22") { println("the number is \(twentytwo)") } else { println("not a number") }
In the current implementation, struct and enum initializers can return nil at any point inside the initializer, but class initializers can only return nil after all of the stored properties of the object have been initialized and
self.initorsuper.inithas been called. Ifself.initorsuper.initis used to delegate to a failable initializer, then thenilreturn is implicitly propagated through the current initializer if the called initializer fails. -
The
RawRepresentableprotocol that enums with raw types implicitly conform to has been redefined to take advantage of failable initializers. ThefromRaw(RawValue)static method has been replaced with an initializerinit?(rawValue: RawValue), and thetoRaw()method has been replaced with arawValueproperty. Enums with raw types can now be used like this:enum Foo: Int { case A = 0, B = 1, C = 2 } let foo = Foo(rawValue: 2)! // formerly 'Foo.fromRaw(2)!' println(foo.rawValue) // formerly 'foo.toRaw()'
- Characters can no longer be concatenated using
+. UseString(c1) + String(c2)instead.
- When force-casting between arrays of class or
@objcprotocol types usinga as [C], type checking is now deferred until the moment each element is accessed. Because bridging conversions from NSArray are equivalent to force-casts from[NSArray], this makes certain Array round-trips through Objective-C codeO(1)instead ofO(N).
-
RawOptionSetTypenow implementsBitwiseOperationsType, so importedNS_OPTIONSnow support the bitwise assignment operators|=,&=, and^=. It also no longer implementsBooleanType; to check if an option set is empty, compare it tonil. -
Types implementing
BitwiseOperationsTypenow automatically support the bitwise assignment operators|=,&=, and^=. -
Optionals can now be coalesced with default values using the
??operator.??is a short-circuiting operator that takes an optional on the left and a non-optional expression on the right. If the optional has a value, its value is returned as a non-optional; otherwise, the expression on the right is evaluated and returned:var sequence: [Int] = [] sequence.first ?? 0 // produces 0, because sequence.first is nil sequence.append(22) sequence.first ?? 0 // produces 22, the value of sequence.first
-
The optional chaining
?operator can now be mutated through, like!. The assignment and the evaluation of the right-hand side of the operator are conditional on the presence of the optional value:var sequences = ["fibonacci": [1, 1, 2, 3, 4], "perfect": [6, 28, 496]] sequences["fibonacci"]?[4]++ // Increments element 4 of key "fibonacci" sequences["perfect"]?.append(8128) // Appends to key "perfect" sequences["cubes"]?[3] = 3*3*3 // Does nothing; no "cubes" key
Note that optional chaining still flows to the right, so prefix increment operators are not included in the chain, so this won't type-check:
++sequences["fibonacci"]?[4] // Won't type check, can't '++' Int?
-
The swift command line interface is now divided into an interactive driver
swift, and a batch compilerswiftc:swift [options] input-file [program-arguments] Runs the script 'input-file' immediately, passing any program-arguments to the script. Without any input files, invokes the repl. swiftc [options] input-filenames The familiar swift compiler interface: compiles the input-files according to the mode options like -emit-object, -emit-executable, etc. -
For greater clarity and explicitness when bypassing the type system,
reinterpretCasthas been renamedunsafeBitCast, and it has acquired a (required) explicit type parameter. Solet x: T = reinterpretCast(y)
becomes
let x = unsafeBitCast(y, T.self)
-
Because their semantics were unclear, the methods
asUnsigned(on the signed integer types) andasSigned(on the unsigned integer types) have been replaced. The new idiom is explicit construction of the target type using thebitPattern:argument label. So,myInt.asUnsigned()
has become
UInt(bitPattern: myInt)
-
To better follow Cocoa naming conventions and to encourage immutability, The following pointer types were renamed:
Old Name New Name UnsafePointer<T>UnsafeMutablePointer<T>ConstUnsafePointer<T>UnsafePointer<T>AutoreleasingUnsafePointer<T>AutoreleasingUnsafeMutablePointer<T>Note that the meaning of
UnsafePointerhas changed from mutable to immutable. As a result, some of your code may fail to compile when assigning to anUnsafePointer's.memoryproperty. The fix is to change yourUnsafePointer<T>into anUnsafeMutablePointer<T>. -
The optional unwrapping operator
x!can now be assigned through, and mutating methods and operators can be applied through it:var x: Int! = 0 x! = 2 x!++ // Nested dictionaries can now be mutated directly: var sequences = ["fibonacci": [1, 1, 2, 3, 0]] sequences["fibonacci"]![4] = 5 sequences["fibonacci"]!.append(8)
-
The
@auto_closureattribute has been renamed to@autoclosure. -
There is a new
dynamicdeclaration modifier. When applied to a method, property, subscript, or initializer, it guarantees that references to the declaration are always dynamically dispatched and never inlined or devirtualized, and that the method binding can be reliably changed at runtime. The implementation currently relies on the Objective-C runtime, sodynamiccan only be applied to@objc-compatibledeclarations for now.@objcnow only makes a declaration visible to Objective-C; the compiler may now use vtable lookup or direct access to access (non-dynamic)@objcdeclarations.class Foo { // Always accessed by objc_msgSend dynamic var x: Int // Accessed by objc_msgSend from ObjC; may be accessed by vtable // or by static reference in Swift @objc var y: Int // Not exposed to ObjC (unless Foo inherits NSObject) var z: Int }
dynamicenables KVO, proxying, and other advanced Cocoa features to work reliably with Swift declarations. -
Clang submodules can now be imported:
import UIKit.UIGestureRecognizerSubclass
-
The numeric optimization levels
-O[0-3]have been removed in favor of the named levels-Ononeand-O. -
The
-Ofastoptimization flag has been renamed to-Ounchecked. We will accept both names for now and remove-Ofastin a later build. -
An initializer that overrides a designated initializer from its superclass must be marked with the
overridekeyword, so that all overrides in the language consistently require the use ofoverride. For example:class A { init() { } } class B : A { override init() { super.init() } }
-
Required initializers are now more prominent in several ways. First, a (non-final) class that conforms to a protocol that contains an initializer requirement must provide a required initializer to satisfy that requirement. This ensures that subclasses will also conform to the protocol, and will be most visible with classes that conform to NSCoding:
class MyClass : NSObject, NSCoding { required init(coder aDecoder: NSCoder!) { /*... */ } func encodeWithCoder(aCoder: NSCoder!) { /* ... */ } }
Second, because
requiredplaces a significant requirement on all subclasses, therequiredkeyword must be placed on overrides of a required initializer:class MySubClass : MyClass { var title: String = "Untitled" required init(coder aDecoder: NSCoder!) { /*... */ } override func encodeWithCoder(aCoder: NSCoder!) { /* ... */ } }
Finally, required initializers can now be inherited like any other initializer:
class MySimpleSubClass : MyClass { } // inherits the required init(coder:).
-
Access control has been implemented.
publicdeclarations can be accessed from any module.internaldeclarations (the default) can be accessed from within the current module.privatedeclarations can be accessed only from within the current file.
There are still details to iron out here, but the model is in place. The general principle is that an entity cannot be defined in terms of another entity with less accessibility.
Along with this, the generated header for a framework will only include public declarations. Generated headers for applications will include public and internal declarations.
-
CGFloatis now a distinct floating-point type that wraps either aFloat(on 32-bit architectures) or aDouble(on 64-bit architectures). It provides all of the same comparison and arithmetic operations of Float and Double, and can be created using numeric literals. -
The immediate mode
swift -inow works for writing#!scripts that take command line arguments. The-ioption to the swift driver must now come at the end of the compiler arguments, directly before the input filename. Any arguments that come after-iand the input filename are treated as arguments to the interpreted file and forwarded toProcess.arguments. -
Type inference for
for..inloops has been improved to consider the sequence along with the element pattern. For example, this accepts the following loops that were previously rejected:for i: Int8 in 0..<10 { } for i: Float in 0.0...10.0 { }
-
Introduced the new
BooleanLiteralConvertibleprotocol, which allows user-defined types to support Boolean literals.trueandfalseare nowBooleanconstants and keywords. -
The
@final,@lazy,@requiredand@optionalattributes are now considered to be declaration modifiers - they no longer require (or allow) an@sign. -
The
@prefix,@infix, and@postfixattributes have been changed to declaration modifiers, so they are no longer spelled with an@sign.
Operator declarations have been rearranged fromoperator prefix +toprefix operator +for consistency.
-
C function pointer types are now imported as
CFunctionPointer<T>, whereTis a Swift function type.CFunctionPointerandCOpaquePointercan be explicitly constructed from one another, but they do not freely convert, nor isCFunctionPointercompatible with Swift closures.Example:
int (*)(void)becomesCFunctionPointer<(Int) -> Void>. -
The interop model for pointers in C APIs has been simplified. Most code that calls C functions by passing arrays, UnsafePointers, or the addresses of variables with
&xdoes not need to change. However, theCConstPointerandCMutablePointerbridging types have been removed, and functions and methods are now imported as and overridden by taking UnsafePointer andConstUnsafePointerdirectly.Voidpointers are now imported as(Const)UnsafePointer<Void>;COpaquePointeris only imported for opaque types now. -
Arraytypes are now spelled with the brackets surrounding the element type. For example, an array ofIntis written as:var array: [Int]
-
Dictionarytypes can now be spelled with the syntax[K : V], whereKis the key type andVis the value type. For example:var dict: [String : Int] = ["Hello" : 1, "World" : 2]
The type
[K : V]is syntactic sugar forDictionary<K, V>; nothing else has changed. -
The
@IBOutletattribute no longer implicitly (and invisibly) changes the type of the declaration it is attached to. It no longer implicitly makes variables be an implicitly unwrapped optional and no longer defaults them to weak. -
The
\x,\uand\Uescape sequences in string literals have been consolidated into a single and less error prone\u{123456}syntax.
-
The half-open range operator has been renamed from
..to..<to reduce confusion. The..<operator is precedented in Groovy (among other languages) and makes it much more clear that it doesn't include the endpoint. -
Class objects such as
NSObject.selfcan now be converted toAnyObjectand used as object values. -
Objective-C protocol objects such as
NSCopying.selfcan now be used as instances of theProtocolclass, such as in APIs such as XPC. -
Arrays now have full value semantics: both assignment and initialization create a logically-distinct object
-
The
sortfunction and array method modify the target in-place. A newsortedfunction and array method are non-mutating, creating and returning a new collection.
-
sort,map,filter, andreducemethods onArrays accept trailing closures:let a = [5, 6, 1, 3, 9] a.sort{ $0 > $1 } println(a) // [9, 6, 5, 3, 1] println(a.map{ $0 * 2 }) // [18, 12, 10, 6, 2] println(a.map{ $0 * 2 }.filter{ $0 < 10}) // [6, 2] println(a.reduce(1000){ $0 + $1 }) // 1024 (no kidding)
-
A lazy
map()function in the standard library works on anySequence. Example:class X { var value: Int init(_ value: Int) { self.value = value println("created X(\(value))") } } // logically, this sequence is X(0), X(1), X(2), ... X(50) let lazyXs = map(0..50){ X($0) } // Prints "created X(...)" 4 times for x in lazyXs { if x.value == 4 { break } }
-
There's a similar lazy
filter()function:// 0, 10, 20, 30, 40 let tens = filter(0..50) { $0 % 10 == 0 } let tenX = map(tens){ X($0) } // 5 lazy Xs let tenXarray = Array(tenX) // Actually creates those Xs
-
Weak pointers of classbound protocol type work now.
-
IBOutletsnow default to weak pointers with implicit optional type (T!). -
NSArray*parameters and result types of Objective-C APIs are now imported asAnyObject[]!, i.e., an implicitly unwrapped optional array storingAnyObjectvalues. For example,NSView's constraints property@property (readonly) NSArray *constraints;is now imported as
var constraints: AnyObject[]!
Note that one can implicitly convert between an
AnyObject[]and anNSArray(in both directions), so (for example) one can still explicitly useNSArrayif desired:var array: NSArray = view.constraints
Swift arrays bridge to
NSArraysimilarly to the way Swift strings bridge toNSString. -
ObjCMutablePointerhas been renamedAutoreleasingUnsafePointer. -
UnsafePointer(andAutoreleasingUnsafePointer)'sset()andget()have been replaced with a property calledmemory.-
Previously you would write:
val = p.get() p.set(val)
-
Now you write:
val = p.memory p.memory = val
-
-
Removed shorthand
x as T!; instead use(x as T)!x as T!now means "x as implicitly unwrapped optional".
-
Range operators
..and...have been switched.1..3now means 1,21...3now means 1,2,3
-
The pound sign (
#) is now used instead of the back-tick (`) to mark an argument name as a keyword argument, e.g.,func moveTo(#x: Int, #y: Int) { ... } moveTo(x: 5, y: 7)
-
Objective-C factory methods are now imported as initializers. For example,
NSColor's+colorWithRed:green:blue:alphabecomesinit(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
which allows an
NSColorto be created as, e.g.,NSColor(red: 0.5, green: 0.25, blue: 0.25, alpha: 0.5)
Factory methods are identified by their kind (class methods), name (starts with words that match the words that end the class name), and result type (
instancetypeor the class type). -
Objective-C properties of some
CFtype are no longer imported asUnmanaged. -
REPL mode now uses LLDB, for a greatly-expanded set of features. The colon prefix now treats the rest of the line as a command for LLDB, and entering a single colon will drop you into the debugging command prompt. Most importantly, crashes in the REPL will now drop you into debugging mode to see what went wrong.
If you do have a need for the previous REPL, pass
-integrated-repl. -
In a UIKit-based application, you can now eliminate your 'main.swift' file and instead apply the
@UIApplicationMainattribute to yourUIApplicationDelegateclass. This will cause themainentry point to the application to be automatically generated as follows:UIApplicationMain(argc, argv, nil, NSStringFromClass(YourApplicationDelegate.self))
If you need nontrivial logic in your application entry point, you can still write out a
main.swift. Note that@UIApplicationMainandmain.swiftare mutually exclusive.
-
weak pointers now work with implicitly unchecked optionals, enabling usecases where you don't want to
!every use of a weak pointer. For example:weak var myView : NSView!
of course, they still work with explicitly checked optionals like
NSView? -
Dictionary subscripting now takes/returns an optional type. This allows querying a dictionary via subscripting to gracefully fail. It also enables the idiom of removing values from a dictionary using
dict[key] = nil. As part of this,deleteKeyis no longer available. -
Stored properties may now be marked with the
@lazyattribute, which causes their initializer to be evaluated the first time the property is touched instead of when the enclosing type is initialized. For example:func myInitializer() -> Int { println("hello\n"); return 42 } class MyClass { @lazy var aProperty = myInitializer() } var c = MyClass() // doesn't print hello var tmp = c.aProperty // prints hello on first access tmp = c.aProperty // doesn't print on subsequent loads. c = MyClass() // doesn't print hello c.aProperty = 57 // overwriting the value prevents it from ever running
Because lazy properties inherently rely on mutation of the property, they cannot be
lets. They are currently also limited to being members of structs and classes (they aren't allowed as local or global variables yet) and cannot be observed withwillSet/didSetyet. -
Closures can now specify a capture list to indicate with what strength they want to capture a value, and to bind a particular field value if they want to.
Closure capture lists are square-bracket delimited and specified before the (optional) argument list in a closure. Each entry may be specified as
weakorunownedto capture the value with a weak or unowned pointer, and may contain an explicit expression if desired. Some examples:takeClosure { print(self.title) } // strong capture takeClosure { [weak self] in print(self!.title) } // weak capture takeClosure { [unowned self] in print(self.title) } // unowned capture
You can also bind arbitrary expression to named values in the capture list. The expression is evaluated when the closure is formed, and captured with the specified strength. For example:
// weak capture of "self.parent" takeClosure { [weak tmp = self.parent] in print(tmp!.title) }
The full form of a closure can take a signature (an argument list and optionally a return type) if needed. To use either the capture list or the signature, you must specify the context sensitive
inkeyword. Here is a (weird because there is no need forunowned) example of a closure with both:myNSSet.enumerateObjectsUsingBlock { [unowned self] (obj, stop) in self.considerWorkingWith(obj) }
-
The word
withis now removed from the first keyword argument name if an initialized imported from Objective-C. For example, instead of buildingUIColoras:UIColor(withRed: r, green: g, blue: b, alpha: a)
it will now be:
UIColor(red: r, green: g, blue: b, alpha: a)
-
Dictionarycan be bridged toNSDictionaryand vice versa:-
NSDictionaryhas an implicit conversion toDictionary<NSObject, AnyObject>. It bridges in O(1), without memory allocation. -
Dictionary<K, V>has an implicit conversion toNSDictionary.Dictionary<K, V>bridges toNSDictionaryiff bothKandVare bridged. Otherwise, a runtime error is raised.Depending on
KandVthe operation can beO(1)without memory allocation, orO(N)with memory allocation.
-
-
Single-quoted literals are no longer recognized. Use double-quoted literals and an explicit type annotation to define
CharactersandUnicodeScalars:var ch: Character = "a" var us: UnicodeScalar = "a"
-
The use of keyword arguments is now strictly enforced at the call site. For example, consider this method along with a call to it:
class MyColor { func mixColorWithRed(red: Float, green: Float, blue: Float) { /* ... */ } } func mix(color: MyColor, r: Float, g: Float, b: Float) { color.mixColorWithRed(r, g, b) }
The compiler will now complain about the missing
green:andblue:labels, with a Fix-It to correct the code:color.swift:6:24: error: missing argument labels 'green:blue:' in call color.mixColorWithRed(r, g, b) ^ green: blue:The compiler handles missing, extraneous, and incorrectly-typed argument labels in the same manner. Recall that one can make a parameter a keyword argument with the back-tick or remove a keyword argument with the underscore.
class MyColor { func mixColor(`red: Float, green: Float, blue: Float) { /* ... */ } func mixColorGuess(red: Float, _ green: Float, _ blue: Float) { /* ... */ } } func mix(color: MyColor, r: Float, g: Float, b: Float) { color.mixColor(red: r, green: g, blue: b) // okay: all keyword arguments color.mixColorGuess(r, g, b) // okay: no keyword arguments }
Arguments cannot be re-ordered unless the corresponding parameters have default arguments. For example, given:
func printNumber(`number: Int, radix: Int = 10, separator: String = ",") { }
The following three calls are acceptable because only the arguments for defaulted parameters are re-ordered relative to each other:
printNumber(number: 256, radix: 16, separator: "_") printNumber(number: 256, separator: "_") printNumber(number: 256, separator: ",", radix: 16)
However, this call:
printNumber(separator: ",", radix: 16, number: 256)
results in an error due to the re-ordering:
printnum.swift:7:40: error: argument 'number' must precede argument 'separator' printNumber(separator: ",", radix: 16, number: 256) ~~~~~~~~~~~~~~ ^ ~~~ -
;can no longer be used to demarcate an empty case in a switch statement, usebreakinstead.
-
The compiler's ability to diagnose many common kinds of type check errors has improved. (
expression does not type-checkhas been retired.) -
Ranges can be formed with floating point numbers, e.g.
0.0 .. 100.0. -
Convenience initializers are now spelled as
convenience initinstead of with the-> Selfsyntax. For example:class Foo { init(x : Int) {} // designated initializer convenience init() { self.init(42) } // convenience initializer }
You still cannot declare designated initializers in extensions, only convenience initializers are allowed.
-
Reference types using the CoreFoundation runtime are now imported as class types. This means that Swift will automatically manage the lifetime of a
CFStringRefthe same way that it manages the lifetime of anNSString.In many common cases, this will just work. Unfortunately, values are returned from
CF-style APIs in a wide variety of ways, and unlike Objective C methods, there simply isn't enough consistency for Swift to be able to safely apply the documented conventions universally. The framework teams have already audited many of the most importantCF-style APIs, and those APIs should be imported without a hitch into Swift. For all the APIs which haven't yet been audited, we must import return types using theUnmanagedtype. This type allows the programmer to control exactly how the object is passed.For example:
// CFBundleGetAllBundles() returns an Unmanaged<CFArrayRef>. // From the documentation, we know that it returns a +0 value. let bundles = CFBundleGetAllBundles().takeUnretainedValue() // CFRunLoopCopyAllModes() returns an Unmanaged<CFArrayRef>. // From the documentation, we know that it returns a +1 value. let modes = CFRunLoopCopyAllModes(CFRunLoopGetMain()).takeRetainedValue()
You can also use
Unmanagedtypes to pass and return objects indirectly, as well as to generate unbalanced retains and releases if you really require them.The API of the Unmanaged type is still in flux, and your feedback would be greatly appreciated.
-
The
@NSManagedattribute can be applied to the properties of anNSManagedObjectsubclass to indicate that they should be handled by CoreData:class Employee : NSManagedObject { @NSManaged var name: String @NSManaged var department: Department }
-
The
@weakand@unownedattributes have become context sensitive keywords instead of attributes. To declare aweakorunownedpointer, use:weak var someOtherWindow : NSWindow? unowned var someWindow : NSWindow
... with no
@on theweak/unowned.
-
Swift now supports a
#elseifform for build configurations, e.g.:#if os(OSX) typealias SKColor = NSColor #elseif os(iOS) typealias SKColor = UIColor #else typealias SKColor = Green #endif
-
You can now use the
trueandfalseconstants in build configurations, allowing you to emulate the C idioms of#if 0(but spelled#if false). -
breaknow breaks out of switch statements. -
It is no longer possible to specify
@mutatingas an attribute, you may only use it as a keyword, e.g.:struct Pair { var x, y : Int mutating func nuke() { x = 0; y = 0 } }
The former
@!mutatingsyntax used to mark setters as non-mutating is now spelled with thenonmutatingkeyword. Both mutating and nonmutating are context sensitive keywords. -
NSLogis now available from Swift code. -
The parser now correctly handles expressions like
var x = Int[]()to create an empty array of integers. Previously you'd have to use syntax likeArray<Int>()to get this. Now that this is all working, please prefer to useInt[]consistently instead ofArray<Int>. -
Characteris the new character literal type:var x = 'a' // Infers 'Character' type
You can force inference of
UnicodeScalarlike this:var scalar: UnicodeScalar = 'a'
Charactertype represents a Unicode extended grapheme cluster (to put it simply, a grapheme cluster is what users think of as a character: a base plus any combining marks, or other cases explained in Unicode Standard Annex #29).
-
Loops and switch statements can now carry labels, and you can
break/continueto those labels. These use conventional C-style label syntax, and should be dedented relative to the code they are in. An example:func breakContinue(x : Int) -> Int { Outer: for a in 0..1000 { Switch: switch x { case 42: break Outer case 97: continue Outer case 102: break Switch case 13: continue // continue always works on loops. case 139: break // break will break out of the switch (but see below) } } }
-
We are changing the behavior of
breakto provide C-style semantics, to allow breaking out of a switch statement. Previously, break completely ignored switches so that it would break out of the nearest loop. In the example above,case 139would break out of theOuterloop, not theSwitch.In order to avoid breaking existing code, we're making this a compile time error instead of a silent behavior change. If you need a solution for the previous behavior, use labeled break.
This error will be removed in a week or two.
-
Cocoa methods and properties that are annotated with the
NS_RETURNS_INNER_POINTERattribute, including-[NSData bytes]and-[{NS,UI}Color CGColor], are now safe to use and follow the same lifetime extension semantics as ARC.
-
Enabling/disabling of asserts
assert(condition, msg)
is enabled/disabled dependent on the optimization level. In debug mode at
-O0asserts are enabled. At higher optimization levels asserts are disabled and no code is generated for them. However, asserts are always type checked even at higher optimization levels.Alternatively, assertions can be disabled/enabled by using the frontend flag
-assert-config Debug, or-assert-config Release. -
Added optimization flag
-Ofast. It disables all assertions (assert), and runtime overflow and type checks. -
The "selector-style" function and initializer declaration syntax is being phased out. For example, this:
init withRed(red: CGFloat) green(CGFloat) blue(CGFloat) alpha(CGFloat)will now be written as:
init(withRed red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
For each parameter, one can have both an argument API name (i.e.,
withRed, which comes first and is used at the call site) and an internal parameter name that follows it (i.e.red, which comes second and is used in the implementation). When the two names are the same, one can simply write the name once and it will be used for both roles (as withgreen,blue, andalphaabove). The underscore (_) can be used to mean "no name", as when the following function/method:func murderInRoom(room:String) withWeapon(weapon: String)is translated to:
func murderInRoom(_ room: String, withWeapon weapon: String)
The compiler now complains when it sees the selector-style syntax and will provide Fix-Its to rewrite to the newer syntax.
Note that the final form of selector syntax is still being hammered out, but only having one declaration syntax, which will be very close to this, is a known.
-
Stored properties can now be marked with the
@NSCopyingattribute, which causes their setter to be synthesized with a copy tocopyWithZone:. This may only be used with types that conform to theNSCopyingprotocol, or option types thereof. For example:@NSCopying var myURL : NSURL
This fills the same niche as the (
copy) attribute on Objective-C properties.
-
Optional variables and properties are now default-initialized to
nil:class MyClass { var cachedTitle: String? // "= nil" is implied }
-
@IBOutlethas been improved in a few ways:-
IBOutletscan now be@uncheckedoptional. -
An
IBOutletdeclared as non-optional, i.e.,@IBOutlet var button: NSButton
will be treated as an
@uncheckedoptional. This is considered to be the best practice way to write an outlet, unless you want to explicitly handle the null case - in which case, useNSButton?as the type. Either way, the= nilthat was formerly required is now implicit.
-
-
The precedence of
isandasis now higher than comparisons, allowing the following sorts of things to be written without parens:if x is NSButton && y is NSButtonCell { ... } if 3/4 as Float == 6/8 as Float { ... }
-
Objective-C blocks are now transparently bridged to Swift closures. You never have to write
@objc_blockwhen writing Objective-C-compatible methods anymore. Block parameters are now imported as unchecked optional closure types, allowingnilto be passed.
-
Dictionarychanges:-
Elementsare now tuples, so you can writefor (k, v) in d { // ... }
-
keysandvaluesproperties, which areCollectionsprojecting the corresponding aspect of each element.Dictionaryindices are usable with theirkeysandvaluesproperties, so:for i in indices(d) { let (k, v) = d[i] assert(k == d.keys[i]) assert(v == d.values[i]) }
-
-
Semicolon can be used as a single no-op statement in otherwise empty cases in
switchstatements:switch x { case 1, 2, 3: print("x is 1, 2 or 3") default: ; }
-
overrideis now a context sensitive keyword, instead of an attribute:class Base { var property: Int { return 0 } func instanceFunc() {} class func classFunc() {} } class Derived : Base { override var property: Int { return 1 } override func instanceFunc() {} override class func classFunc() {} }
-
Prefix splitting for imported enums has been revised again due to feedback:
- If stripping off a prefix would leave an invalid identifier (like
10_4), leave one more word in the result than would otherwise be there (Behavior10_4). - If all enumerators have a
kprefix (forconstant) and the enum doesn't, thekshould not be considered when finding the common prefix. - If the enum name is a plural (like
NSSomethingOptions) and the enumerator names use the singular form (NSSomethingOptionMagic), this is considered a matching prefix (but only if nothing follows the plural).
- If stripping off a prefix would leave an invalid identifier (like
-
Cocoa APIs that take pointers to plain C types as arguments now get imported as taking the new
CMutablePointer<T>andCConstPointer<T>types instead ofUnsafePointer<T>. These new types allow implicit conversions from Swiftinoutparameters and from Swift arrays:let rgb = CGColorSpaceCreateDeviceRGB() // CGColorRef CGColorCreate(CGColorSpaceRef, const CGFloat*); let white = CGColorCreate(rgb, [1.0, 1.0, 1.0]) var s = 0.0, c = 0.0 // void sincos(double, double*, double*); sincos(M_PI/2, &s, &c)
Pointers to pointers to ObjC classes, such as
NSError**, get imported asObjCMutablePointer<NSError?>. This type doesn't work with arrays, but accepts inouts ornil:var error: NSError? = nil let words = NSString.stringWithContentsOfFile("/usr/share/dict/words", encoding: .UTF8StringEncoding, error: &error)
Voidpointer parameters can be passed an array or inout of any type:// + (NSData*)dataWithBytes:(const void*)bytes length:(NSUInteger)length; let data = NSData.dataWithBytes([1.5, 2.25, 3.125], length: sizeof(Double.self) * 3) var fromData = [0.0, 0.0, 0.0] // - (void)getBytes:(void*)bytes length:(NSUInteger)length; data.getBytes(&fromData, length: sizeof(Double.self) * 3)
Note that we don't know whether an API reads or writes the C pointer, so you need to explicitly initialize values (like
sandcabove) even if you know that the API overwrites them.This pointer bridging only applies to arguments, and only works with well- behaved C and ObjC APIs that don't keep the pointers they receive as arguments around or do other dirty pointer tricks. Nonstandard use of pointer arguments still requires
UnsafePointer. -
Objective-C pointer types now get imported by default as the
@unchecked T?optional type. Swift class types no longer implicitly includenil.A value of
@unchecked T?can be implicitly used as a value ofT. Swift will implicitly cause a reliable failure if the value isnil, rather than introducing undefined behavior (as in Objective-C ivar accesses or everything in C/C++) or silently ignoring the operation (as in Objective-C message sends).A value of
@unchecked T?can also be implicitly used as a value ofT?, allowing you explicitly handle the case of anilvalue. For example, if you would like to just silently ignore a message send a la Objective-C, you can use the postfix?operator like so:fieldsForKeys[kHeroFieldKey]?.setEditable(true)
This design allows you to isolate and handle
nilvalues in Swift code without requiring excessive "bookkeeping" boilerplate to use values that you expect to be non-nil.For now, we will continue to import C pointers as non-optional
UnsafePointerandC*Pointertypes; that will be evaluated separately.We intend to provide attributes for Clang to allow APIs to opt in to importing specific parameters, return types, etc. as either the explicit optional type
T?or the simple non-optional typeT. -
The "separated" call syntax, i.e.,
NSColor.colorWithRed(r) green(g) blue(b) alpha(a) UIColor.init withRed(r) green(g) blue(b) alpha(a)is being removed. The compiler will now produce an error and provide Fix-Its to rewrite calls to the "keyword-argument" syntax:
NSColor.colorWithRed(r, green: g, blue: b, alpha: a) UIColor(withRed: r, green:g, blue:b, alpha: a)
-
The
objcattribute now optionally accepts a name, which can be used to provide the name for an entity as seen in Objective-C. For example:class MyType { var enabled: Bool { @objc(isEnabled) get { // ... } } }
The
@objcattribute can be used to name initializers, methods, getters, setters, classes, and protocols. -
Methods, properties and subscripts in classes can now be marked with the
@finalattribute. This attribute prevents overriding the declaration in any subclass, and provides better performance (since dynamic dispatch is avoided in many cases).
-
Attributes on declarations are no longer comma separated.
Old syntax:
@_silgen_name("foo"), @objc func bar() {}New syntax:
@_silgen_name("foo") @objc
The
,was vestigial when the attribute syntax consisted of bracked lists. -
switchnow always requires a statement after acaseordefault.Old syntax:
switch x { case .A: case .B(1): println(".A or .B(1)") default: // Ignore it. }
New syntax:
switch x { case .A, .B(1): println(".A or .B(1)") default: () // Ignore it. }
The following syntax can be used to introduce guard expressions for patterns inside the
case:switch x { case .A where isFoo(), .B(1) where isBar(): ... }
-
Observing properties can now
@overrideproperties in a base class, so you can observe changes that happen to them.class MyAwesomeView : SomeBasicView { @override var enabled : Bool { didSet { println("Something changed") } } ... }
Observing properties still invoke the base class getter/setter (or storage) when accessed.
-
An
ascast can now be forced using the postfix!operator without using parens:class B {} class D {} let b: B = D() // Before let d1: D = (b as D)! // After let d2: D = b as D!
Casts can also be chained without parens:
// Before let b2: B = (((D() as B) as D)!) as B // After let b3: B = D() as B as D! as B
-
ascan now be used inswitchcases to match the result of a checked cast:func printHand(hand: Any) { switch hand { case 1 as Int: print("ace") case 11 as Int: print("jack") case 12 as Int: print("queen") case 13 as Int: print("king") case let numberCard as Int: print("\(numberCard)") case let (a, b) as (Int, Int) where a == b: print("two ") printHand(a) print("s") case let (a, b) as (Int, Int): printHand(a) print(" and a ") printHand(b) case let (a, b, c) as (Int, Int, Int) where a == b && b == c: print("three ") printHand(a) print("s") case let (a, b, c) as (Int, Int, Int): printHand(a) print(", ") printHand(b) print(", and a ") printHand(c) default: print("unknown hand") } } printHand(1, 1, 1) // prints "three aces" printHand(12, 13) // prints "queen and a king"
-
Enums and option sets imported from C/Objective-C still strip common prefixes, but the name of the enum itself is now taken into consideration as well. This keeps us from dropping important parts of a name that happen to be shared by all members.
// NSFileManager.h typedef NS_OPTIONS(NSUInteger, NSDirectoryEnumerationOptions) { NSDirectoryEnumerationSkipsSubdirectoryDescendants = 1UL << 0, NSDirectoryEnumerationSkipsPackageDescendants = 1UL << 1, NSDirectoryEnumerationSkipsHiddenFiles = 1UL << 2 } NS_ENUM_AVAILABLE(10_6, 4_0);
// Swift let opts: NSDirectoryEnumerationOptions = .SkipsPackageDescendants
-
initmethods in Objective-C protocols are now imported as initializers. To conform toNSCoding, you will now need to provideinit withCoder(aDecoder: NSCoder) { ... }
rather than
func initWithCoder(aDecoder: NSCoder) { ... }
-
When a class provides no initializers of its own but has default values for all of its stored properties, it will automatically inherit all of the initializers of its superclass. For example:
class Document { var title: String init() -> Self { self.init(withTitle: "Default title") } init withTitle(title: String) { self.title = title } } class VersionedDocument : Document { var version = 0 // inherits 'init' and 'init withTitle:' from Document }
When one does provide a designated initializer in a subclass, as in the following example:
class SecureDocument : Document { var key: CryptoKey init withKey(key: CryptoKey) -> Self { self.init(withKey: key, title: "Default title") } init withKey(key: CryptoKey) title(String) { self.key = key super.init(withTitle: title) } }
the compiler emits Objective-C method stubs for all of the designated initializers of the parent class that will abort at runtime if called, and which indicate which initializer needs to be implemented. This provides memory safety for cases where an Objective-C initializer (such as
-[Document init]in this example) appears to be inherited, but isn't actually implemented. -
nilmay now be used as a Selector value. This allows calls to Cocoa methods that acceptnilselectors. -
[]and[:]can now be used as the empty array and dictionary literal, respectively. Because these carry no information about their element types, they may only be used in a context that provides this information through type inference (e.g. when passing a function argument). -
Properties defined in classes are now dynamically dispatched and can be overriden with
@override. Currently@overrideonly works with computed properties overriding other computed properties, but this will be enhanced in coming weeks.
-
The
didSetaccessor of an observing property now gets passed in the old value, so you can easily implement an action for when a property changes value. For example:class MyAwesomeView : UIView { var enabled : Bool = false { didSet(oldValue): if oldValue != enabled { self.needsDisplay = true } } ... }
-
The implicit argument name for set and willSet property specifiers has been renamed from
(value)to(newValue). For example:var i : Int { get { return 42 } set { // defaults to (newValue) instead of (value) print(newValue) } }
-
The magic identifier
__FUNCTION__can now be used to get the name of the current function as a string. Like__FILE__and__LINE__, if__FUNCTION__is used as a default argument, the function name of the caller is passed as the argument.func malkovich() { println(__FUNCTION__) } malkovich() // prints "malkovich" func nameCaller(name: String = __FUNCTION__) -> String { return name } func foo() { println(nameCaller()) // prints "foo" } func foo(x: Int) bar(y: Int) { println(nameCaller()) // prints "foo:bar:" }
At top level,
__FUNCTION__gives the module name:println(nameCaller()) // prints your module name
-
Selector-style methods can now be referenced without applying arguments using member syntax
foo.bar:bas:, for instance, to test for the availability of an optional protocol method:func getFrameOfObjectValueForColumn(ds: NSTableViewDataSource, tableView: NSTableView, column: NSTableColumn, row: Int) -> AnyObject? { if let getObjectValue = ds.tableView:objectValueForTableColumn:row: { return getObjectValue(tableView, column, row) } return nil }
-
The compiler now warns about cases where a variable is inferred to have
AnyObject,AnyClass, or()type, since type inferrence can turn a simple mistake (e.g. failing to cast anAnyObjectwhen you meant to) into something with ripple effects. Here is a simple example:t.swift:4:5: warning: variable 'fn' inferred to have type '()', which may be unexpected var fn = abort() ^ t.swift:4:5: note: add an explicit type annotation to silence this warning var fn = abort() ^ : ()If you actually did intend to declare a variable of one of these types, you can silence this warning by adding an explicit type (indicated by the Fixit). See rdar://15263687 and rdar://16252090 for more rationale.
-
x.typehas been renamed tox.dynamicType, and you can usetypeas a regular identifier again.
-
C macros that expand to a single constant string are now imported as global constants. Normal string literals are imported as
CString;NSStringliterals are imported asString. -
All values now have a
selfproperty, exactly equivalent to the value itself:let x = 0 let x2 = x.self
Types also have a
selfproperty that is the type object for that type:let theClass = NSObject.self let theObj = theClass()
References to type names are now disallowed outside of a constructor call or member reference; to get a type object as a value,
T.selfis required. This prevents the mistake of intending to construct an instance of a class but forgetting the parens and ending up with the class object instead:let x = MyObject // oops, I meant MyObject()... return x.description() // ...and I accidentally called +description // instead of -description
-
Initializers are now classified as designated initializers, which are responsible for initializing the current class object and chaining via
super.init, and convenience initializers, which delegate to another initializer and can be inherited. For example:class A { var str: String init() -> Self { // convenience initializer self.init(withString: "hello") } init withString(str: String) { // designated initializer self.str = str } }
When a subclass overrides all of its superclass's designated initializers, the convenience initializers are inherited:
class B { init withString(str: String) { // designated initializer super.init(withString: str) } // inherits A.init() }
Objective-C classes that provide
NS_DESIGNATED_INITIALIZERannotations will have their init methods mapped to designated initializers or convenience initializers as appropriate; Objective-C classes withoutNS_DESIGNATED_INITIALIZERannotations have all of theirinitmethods imported as designated initializers, which is safe (but can be verbose for subclasses). Note that the syntax and terminology is still somewhat in flux. -
Initializers can now be marked as
requiredwith an attribute, meaning that every subclass is required to provide that initializer either directly or by inheriting it from a superclass. To constructclass View { @required init withFrame(frame: CGRect) { ... } } func buildView(subclassObj: View.Type, frame: CGRect) -> View { return subclassObj(withFrame: frame) } class MyView : View { @required init withFrame(frame: CGRect) { super.init(withFrame: frame) } } class MyOtherView : View { // error: must override init withFrame(CGRect). }
-
Properties in Objective-C protocols are now correctly imported as properties. (Previously the getter and setter were imported as methods.)
-
Simple enums with no payloads, including
NS_ENUMs imported from Cocoa, now implicitly conform to the Equatable and Hashable protocols. This means they can be compared with the==and!=operators and can be used asDictionarykeys:enum Flavor { case Lemon, Banana, Cherry } assert(Flavor.Lemon == .Lemon) assert(Flavor.Banana != .Lemon) struct Profile { var sweet, sour: Bool } let flavorProfiles: Dictionary<Flavor, Profile> = [ .Lemon: Profile(sweet: false, sour: true ), .Banana: Profile(sweet: true, sour: false), .Cherry: Profile(sweet: true, sour: true ), ] assert(flavorProfiles[.Lemon].sour)
-
valhas been removed. Long livelet! -
Values whose names clash with Swift keywords, such as Cocoa methods or properties named
class,protocol,type, etc., can now be defined and accessed by wrapping reserved keywords in backticks to suppress their builtin meaning:let `class` = 0 let `type` = 1 let `protocol` = 2 println(`class`) println(`type`) println(`protocol`) func foo(Int) `class`(Int) {} foo(0, `class`: 1)
-
The
overrideattribute is now required when overriding a method, property, or subscript from a superclass. For example:class A { func foo() { } } class B : A { @override func foo() { } // 'override' is required here }
-
We're renaming
valback tolet. The compiler accepts both for this week, next week it will just acceptlet. Please migrate your code this week, sorry for the back and forth on this. -
Swift now supports
#if,#elseand#endifblocks, along with target configuration expressions, to allow for conditional compilation within declaration and statement contexts.Target configurations represent certain static information about the compile-time build environment. They are implicit, hard-wired into the compiler, and can only be referenced within the conditional expression of an
#ifblock.Target configurations are tested against their values via a pseudo-function invocation expression, taking a single argument expressed as an identitifer. The argument represents certain static build-time information.
There are currently two supported target configurations:
os, which can have the valuesOSXoriOSarch, which can have the valuesi386,x86_64,armandarm64Within the context of an
#ifblock's conditional expression, a target configuration expression can evaluate to eithertrueorfalse.For example:
#if arch(x86_64) println("Building for x86_64") #else println("Not building for x86_64") #endif class C { #if os(OSX) func foo() { // OSX stuff goes here } #else func foo() { // non-OSX stuff goes here } #endif }
The conditional expression of an
#ifblock can be composed of one or more of the following expression types:- A unary expression, using
! - A binary expression, using
&&or|| - A parenthesized expression
- A target configuration expression
For example:
#if os(iOS) && !arch(I386) ... #endif
Note that
#if/#else/#endifblocks do not constitute a preprocessor, and must form valid and complete expressions or statements. Hence, the following produces a parser error:class C { #if os(iOS) func foo() {} } #else func bar() {} func baz() {} } #endif
Also note that "active" code will be parsed, typechecked and emitted, while "inactive" code will only be parsed. This is why code in an inactive
#ifor#elseblock will produce parser errors for malformed code. This allows the compiler to detect basic errors in inactive regions.This is the first step to getting functionality parity with the important subset of the C preprocessor. Further refinements are planned for later.
- A unary expression, using
-
Swift now has both fully-closed ranges, which include their endpoint, and half-open ranges, which don't.
(swift) for x in 0...5 { print(x) } ; print('\n') // half-open range 01234 (swift) for x in 0..5 { print(x) } ; print('\n') // fully-closed range 012345
-
Property accessors have a new brace-based syntax, instead of using the former "label like" syntax. The new syntax is:
var computedProperty: Int { get { return _storage } set { _storage = value } } var implicitGet: Int { // This form still works. return 42 } var storedPropertyWithObservingAccessors: Int = 0 { willSet { ... } didSet { ... } }
-
Properties and subscripts now work in protocols, allowing you to do things like:
protocol Subscriptable { subscript(idx1: Int, idx2: Int) -> Int { get set } var prop: Int { get } } func foo(s: Subscriptable) { return s.prop + s[42, 19] }
These can be used for generic algorithms now as well.
-
The syntax for referring to the type of a type,
T.metatype, has been changed toT.Type. The syntax for getting the type of a value,typeof(x), has been changed tox.type. -
DynamicSelfis now calledSelf; the semantics are unchanged. -
destructorhas been replaced withdeinit, to emphasize that it is related toinit. We will refer to these asdeinitializers. We've also dropped the parentheses, i.e.:class MyClass { deinit { // release any resources we might have acquired, etc. } }
-
Class methods defined within extensions of Objective-C classes can now refer to
self, including usinginstancetypemethods. As a result,NSMutableString,NSMutableArray, andNSMutableDictionaryobjects can now be created with their respective literals, i.e.,var dict: NSMutableDictionary = ["a" : 1, "b" : 2]
-
The
Streamprotocol has been renamed back toGenerator,which is precedented in other languages and causes less confusion with I/O streaming. -
The
typekeyword was split into two:staticandclass. One can define static functions and static properties in structs and enums like this:struct S { static func foo() {} static var bar: Int = 0 } enum E { static func foo() {} }
classkeyword allows one to define class properties and class methods in classes and protocols:class C { class func foo() {} class var bar: Int = 0 } protocol P { class func foo() {} class var bar: Int = 0 }
When using
classandstaticin the extension, the choice of keyword depends on the type being extended:extension S { static func baz() {} } extension C { class func baz() {} }
-
The
letkeyword is no longer recognized. Please move toval. -
The standard library has been renamed to
Swift(instead ofswift) to be more consistent with other modules on our platforms. -
NSIntegerand other types that are layout-compatible with Swift standard library types are now imported directly as those standard library types. -
Optional types now support a convenience method named "cache" to cache the result of a closure. For example:
class Foo { var _lazyProperty: Int? var property: Int { return _lazyProperty.cache { computeLazyProperty() } } }
-
We are experimenting with a new message send syntax. For example:
SKAction.colorizeWithColor(SKColor.whiteColor()) colorBlendFactor(1.0) duration(0.0)
When the message send is too long to fit on a single line, subsequent lines must be indented from the start of the statement or declaration. For example, this is a single message send:
SKAction.colorizeWithColor(SKColor.whiteColor()) colorBlendFactor(1.0) duration(0.0)
while this is a message send to colorizeWithColor: followed by calls to
colorBlendFactorandduration(on self or to a global function):SKAction.colorizeWithColor(SKColor.whiteColor()) colorBlendFactor(1.0) // call to 'colorBlendFactor' duration(0.0) // call to 'duration'
-
We are renaming the
letkeyword toval. Theletkeyword didn't work out primarily because it is not a noun, so "defining a let" never sounded right. We chosevaloverconstand other options becausevarandvalhave similar semantics (making syntactic similarity useful), becauseconsthas varied and sordid connotations in C that we don't want to bring over, and because we don't want to punish the "preferred" case with a longer keyword.For migration purposes, the compiler now accepts
letandvalas synonyms,letwill be removed next week. -
Selector arguments in function arguments with only a type are now implicitly named after the selector chunk that contains them. For example, instead of:
func addIntsWithFirst(first : Int) second(second : Int) -> Int { return first+second }
you can now write:
func addIntsWithFirst(first : Int) second(Int) -> Int { return first+second }
if you want to explicitly want to ignore an argument, it is recommended that you continue to use the
_to discard it, as in:func addIntsWithFirst(first : Int) second(_ : Int) -> Int {...}
-
The
@inoutattribute in argument lists has been promoted to a context-sensitive keyword. Where before you might have written:func swap<T>(a : @inout T, b : @inout T) { (a,b) = (b,a) }
You are now required to write:
func swap<T>(inout a : T, inout b : T) { (a,b) = (b,a) }
We made this change because
inoutis a fundamental part of the type system, which attributes are a poor match for. The inout keyword is also orthogonal to thevarandletkeywords (which may be specified in the same place), so it fits naturally there. -
The
@mutatingattribute (which can be used on functions in structs, enums, and protocols) has been promoted to a context-sensitive keyword. Mutating struct methods are now written as:struct SomeStruct { mutating func f() {} }
-
Half-open ranges (those that don't include their endpoint) are now spelled with three
.s instead of two, for consistency with Ruby.(swift) for x in 0...5 { print(x) } ; print('\n') // new syntax 01234
Next week, we'll introduce a fully-closed range which does include its endpoint. This will provide:
(swift) for x in 0..5 { print(x) } ; print('\n') // coming soon 012345
These changes are being released separately so that users have a chance to update their code before its semantics changes.
-
Objective-C properties with custom getters/setters are now imported into Swift as properties. For example, the Objective-C property
@property (getter=isEnabled) BOOL enabled;was previously imported as getter (
isEnabled) and setter (setEnabled) methods. Now, it is imported as a property (enabled). -
didSet/willSetproperties may now have an initial value specified:class MyAwesomeView : UIView { var enabled : Bool = false { // Initial value. didSet: self.needsDisplay = true } ... }
they can also be used as non-member properties now, e.g. as a global variable or a local variable in a function.
-
Objective-C instancetype methods are now imported as methods that return Swift's
DynamicSelftype. WhileDynamicSelfis not generally useful for defining methods in Swift, importing to it eliminates the need for casting with the numerousinstancetypeAPIs, e.g.,let tileNode: SKSpriteNode = SKSpriteNode.spriteNodeWithTexture(tileAtlas.textureNamed("tile\(tileNumber).png"))!
becomes
let tileNode = SKSpriteNode.spriteNodeWithTexture(tileAtlas.textureNamed("tile\(tileNumber).png"))
DynamicSelfwill become more interesting in the coming weeks.
-
ifandwhilestatements can now conditionally bind variables. If the condition of aniforwhilestatement is aletdeclaration, then the right-hand expression is evaluated as anOptionalvalue, and control flow proceeds by considering the binding to betrueif theOptionalcontains a value, orfalseif it is empty, and the variables are available in the true branch. This allows for elegant testing of dynamic types, methods, nullable pointers, and other Optional things:class B : NSObject {} class D : B { func foo() { println("we have a D") } } var b: B = D() if let d = b as D { d.foo() } var id: AnyObject = D() if let foo = id.foo { foo() }
-
When referring to a member of an
AnyObject(orAnyClass) object and using it directly (such as calling it, subscripting, or accessing a property on it), one no longer has to write the?or!. The run-time check will be performed implicitly. For example:func doSomethingOnViews(views: NSArray) { for view in views { view.updateLayer() // no '!' needed } }
Note that one can still test whether the member is available at runtime using
?, testing the optional result, or conditionally binding a variable to the resulting member. -
The
swiftcommand line tool can now create executables and libraries directly, just like Clang. Useswift main.swiftto create an executable andswift -emit-library -o foo.dylib foo.swiftto create a library. -
Object files emitted by Swift are not debuggable on their own, even if you compiled them with the
-goption. This was already true if you had multiple files in your project. To produce a debuggable Swift binary from the command line, you must compile and link in a single step withswift, or pass object files AND swiftmodule files back intoswiftafter compilation. (Or use Xcode.) -
importwill no longer import other source files, only built modules. -
The current directory is no longer implicitly an import path. Use
-I .if you have modules in your current directory.
-
Properties in structs and classes may now have
willSet:anddidSet:observing accessors defined on them:For example, where before you may have written something like this in a class:
class MyAwesomeView : UIView { var _enabled : Bool // storage var enabled : Bool { // computed property get: return _enabled set: _enabled = value self.needDisplay = true } ... }
you can now simply write:
class MyAwesomeView : UIView { var enabled : Bool { // Has storage & observing methods didSet: self.needDisplay = true } ... }
Similarly, if you want notification before the value is stored, you can use
willSet, which gets the incoming value before it is stored:var x : Int { willSet(value): // value is the default and may be elided, as with set: println("changing from \(x) to \(value)") didSet: println("we've got a value of \(x) now.\n") }
The
willSet/didSetobservers are triggered on any store to the property, except stores frominit(), destructors, or from within the observers themselves.Overall, a property now may either be "stored" (the default), "computed" (have a
get:and optionally aset:specifier), or a observed (willSet/didSet) property. It is not possible to have a custom getter or setter on a observed property, since they have storage.Two known-missing bits are:
- (rdar://problem/15920332) didSet/willSet variables need to allow initializers
- (rdar://problem/15922884) support non-member didset/willset properties
Because of the first one, for now, you need to explicitly store an initial value to the property in your
init()method. -
Objective-C properties with custom getter or setter names are (temporarily) not imported into Swift; the getter and setter will be imported individually as methods instead. Previously, they would appear as properties within the Objective-C class, but attempting to use the accessor with the customized name would result in a crash.
The long-term fix is tracked as (rdar://problem/15877160).
-
Computed 'type' properties (that is, properties of types, rather than of values of the type) are now permitted on classes, on generic structs and enums, and in extensions. Stored 'type' properties in these contexts remain unimplemented.
The implementation of stored 'type' properties is tracked as (rdar://problem/15915785) (for classes) and (rdar://problem/15915867) (for generic types).
-
The following command-line flags have been deprecated in favor of new spellings. The old spellings will be removed in the following week's build:
Old Spelling New Spelling -emit-llvm-emit-ir-triple-target-serialize-diagnostics-serialize-diagnostics-path -
Imported
NS_OPTIONStypes now have a default initializer which produces a value with no options set. They can also be initialized to the empty set withnil. These are equivalent:var x = NSMatchingOptions() var y: NSMatchingOptions = nil
-
The swift binary no longer has an SDK set by default. Instead, you must do one of the following:
- pass an explicit
-sdk /path/to/sdk - set
SDKROOTin your environment - run
swiftthroughxcrun, which setsSDKROOTfor you
- pass an explicit
-
letdeclarations can now be used as struct/class properties. Aletproperty is mutable withininit(), and immutable everywhere else.class C { let x = 42 let y : Int init(y : Int) { self.y = y // ok, self.y is mutable in init() } func test() { y = 42 // error: 'y' isn't mutable } }
-
The immutability model for structs and enums is complete, and arguments are immutable by default. This allows the compiler to reject mutations of temporary objects, catching common bugs. For example, this is rejected:
func setTo4(a : Double[]) { a[10] = 4.0 // error: 'a' isn't mutable } ... setTo4(someArray)
since
ais semantically a copy of the array passed into the function. The proper fix in this case is to mark the argument is@inout, so the effect is visible in the caller:func setTo4(a : @inout Double[]) { a[10] = 4.0 // ok: 'a' is a mutable reference } ... setTo4(&someArray)
Alternatively, if you really just want a local copy of the argument, you can mark it
var. The effects aren't visible in the caller, but this can be convenient in some cases:func doStringStuff(var s : String) { s += "foo" print(s) }
-
Objective-C instance variables are no longer imported from headers written in Objective-C. Previously, they would appear as properties within the Objective-C class, but trying to access them would result in a crash. Additionally, their names can conflict with property names, which confuses the Swift compiler, and there are no patterns in our frameworks that expect you to access a parent or other class's instance variables directly. Use properties instead.
-
The
NSObjectprotocol is now imported under the nameNSObjectProtocol(rather thanNSObjectProto).
-
Improved deallocation of Swift classes that inherit from Objective-C classes: Swift destructors are implemented as
-deallocmethods that automatically call the superclass's-dealloc. Stored properties are released right before the object is deallocated (using the same mechanism as ARC), allowing properties to be safely used in destructors. -
Subclasses of
NSManagedObjectare now required to provide initial values for each of their stored properties. This permits initialization of these stored properties directly after +alloc to provide memory safety with CoreData's dynamic subclassing scheme. -
letdeclarations are continuing to make slow progress. Curried and selector-style arguments are now immutable by default, andletdeclarations now get proper debug information.
-
The
statickeyword changed totype. One can now define "type functions" and "type variables" which are functions and variables defined on a type (rather than on an instance of the type), e.g.,class X { type func factory() -> X { ... } type var version: Int }
The use of
staticwas actively misleading, since type methods on classes are dynamically dispatched (the same as Objective-C+methods).Note that
typeis a context-sensitive keyword; it can still be used as an identifier. -
Strings have a new native UTF-16 representation that can be converted back and forth to
NSStringat minimal cost. String literals are emitted as UTF-16 for string types that support it (including Swift'sString). -
Initializers can now delegate to other initializers within the same class by calling
self.init. For example:class A { } class B : A { var title: String init() { // note: cannot access self before delegating self.init(withTitle: "My Title") } init withTitle(title: String) { self.title = title super.init() } }
-
Objective-C protocols no longer have the
Protosuffix unless there is a collision with a class name. For example,UITableViewDelegateis now imported asUITableViewDelegaterather thanUITableViewDelegateProto. Where there is a conflict with a class, the protocol will be suffixed withProto, as inNSObject(the class) andNSObjectProto(the protocol).
-
Happy New Year
-
Division and remainder arithmetic now trap on overflow. Like with the other operators, one can use the "masking" alternatives to get non-trapping behavior. The behavior of the non-trapping masking operators is defined:
x &/ 0 == 0 x &% 0 == 0 SIGNED_MIN_FOR_TYPE &/ -1 == -1 // i.e. Int8: -0x80 / -1 == -0x80 SIGNED_MIN_FOR_TYPE &% -1 == 0
-
Protocol conformance checking for
@mutatingmethods is now implemented: an@mutatingstruct method only fulfills a protocol requirement if the protocol method was itself marked@mutating:protocol P { func nonmutating() @mutating func mutating() } struct S : P { // Error, @mutating method cannot implement non-@mutating requirement. @mutating func nonmutating() {} // Ok, mutating allowed, but not required. func mutating() {} }
As before, class methods never need to be marked
@mutating(and indeed, they aren't allowed to be marked as such).
-
Merry Christmas
-
The setters of properties on value types (structs/enums) are now
@mutatingby default. To mark a setter non-mutating, use the@!mutatingattribute. -
Compiler inserts calls to
super.init()into the class initializers that do not call any initializers explicitly. -
A
mapmethod with the semantics of Haskell'sfmapwas added toArray<T>. Map applies a functionf: T->Uto the values stored in the array and returns an Array. So,(swift) func names(x: Int[]) -> String[] { return x.map { "<" + String($0) + ">" } } (swift) names(Array<Int>()) // r0 : String[] = [] (swift) names([3, 5, 7, 9]) // r1 : String[] = ["<3>", "<5>", "<7>", "<9>"]
-
Global variables and static properties are now lazily initialized on first use. Where you would use
dispatch_onceto lazily initialize a singleton object in Objective-C, you can simply declare a global variable with an initializer in Swift. Likedispatch_once, this lazy initialization is thread safe.Unlike C++ global variable constructors, Swift global variables and static properties now never emit static constructors (and thereby don't raise build warnings). Also unlike C++, lazy initialization naturally follows dependency order, so global variable initializers that cross module boundaries don't have undefined behavior or fragile link order dependencies.
-
Swift has the start of an immutability model for value types. As part of this, you can now declare immutable value bindings with a new
letdeclaration, which is semantically similar to defining a get-only property:let x = foo() print(x) // ok x = bar() // error: cannot modify an immutable value swap(&x, &y) // error: cannot pass an immutable value as @inout parameter x.clear() // error: cannot call mutating method on immutable value getX().clear() // error: cannot mutate a temporary
In the case of bindings of class type, the bound object itself is still mutable, but you cannot change the binding.
let r = Rocket() r.blastOff() // Ok, your rocket is mutable. r = Rocket() // error: cannot modify an immutable binding.
In addition to the
letdeclaration itself,selfon classes, and a few other minor things have switched to immutable bindings.A pivotal part of this is that methods of value types (structs and enums) need to indicate whether they can mutate self - mutating methods need to be disallowed on let values (and get-only property results, temporaries, etc) but non-mutating methods need to be allowed. The default for a method is that it does not mutate
self, though you can opt into mutating behavior with a new@mutatingattribute:struct MyWeirdCounter { var count : Int func empty() -> Bool { return count == 0 } @mutating func reset() { count = 0 } ... } let x = MyWeirdCounter() x.empty() // ok x.reset() // error, cannot mutate immutable 'let' value
One missing piece is that the compiler does not yet reject mutations of self in a method that isn't marked
@mutating. That will be coming soon. Related to methods are properties. Getters and setters can be marked mutating as well:extension MyWeirdCounter { var myproperty : Int { get: return 42 @mutating set: count = value*2 } }
The intention is for setters to default to mutating, but this has not been implemented yet. There is more to come here.
-
A
mapmethod with the semantics of Haskell'sfmapwas added toOptional<T>. Map applies a functionf: T->Uto any value stored in anOptional<T>, and returns anOptional<U>. So,(swift) func nameOf(x: Int?) -> String? { return x.map { "<" + String($0) + ">" } } (swift) (swift) var no = nameOf(.None) // Empty optional in... // no : String? = <unprintable value> (swift) no ? "yes" : "no" // ...empty optional out // r0 : String = "no" (swift) (swift) nameOf(.Some(42)) // Non-empty in // r1 : String? = <unprintable value> (swift) nameOf(.Some(42))! // Non-empty out // r2 : String = "<42>"
-
Cocoa types declared with the
NS_OPTIONSmacro are now available in Swift. LikeNS_ENUMtypes, their values are automatically shortened based on the common prefix of the value names in Objective-C, and the name can be elided when type context provides it. They can be used inifstatements using the&,|,^, and~operators as in C:var options: NSJSONWritingOptions = .PrettyPrinted if options & .PrettyPrinted { println("pretty-printing enabled") }
We haven't yet designed a convenient way to author
NS_OPTIONS-like types in Swift.
-
Objective-C
idis now imported asAnyObject(formerly known asDynamicLookup), Objective-CClassis imported asAnyClass. -
The casting syntax
x as Tnow permits both implicit conversions (in which case it produces a value of typeT) and for runtime-checked casts (in which case it produces a value of typeT?that will be.Some(casted x)on success and.Noneon failure). An example:func f(x: AnyObject, y: NSControl) { var view = y as NSView // has type 'NSView' var maybeView = x as NSView // has type NSView? }
-
The precedence levels of binary operators has been redefined, with a much simpler model than C's. This is with a goal to define away classes of bugs such as those caught by Clang's
-Wparentheseswarnings, and to make it actually possible for normal humans to reason about the precedence relationships without having to look them up.We ended up with 6 levels, from tightest binding to loosest:
exponentiative: <<, >> multiplicative: *, /, %, & additive: +, -, |, ^ comparative: ==, !=, <, <=, >=, > conjunctive: && disjunctive: || -
The
Enumerableprotocol has been renamedSequence. -
The
Chartype has been renamedUnicodeScalar. The preferred unit of string fragments for users is calledCharacter. -
Initialization semantics for classes, structs and enums init methods are now properly diagnosed by the compiler. Instance variables now follow the same initialization rules as local variables: they must be defined before use. The initialization model requires that all properties with storage in the current class be initialized before
super.initis called (or, in a root class, before any method is called onself,and before the final return).For example, this will yield an error:
class SomeClass : SomeBase { var x : Int init() { // error: property 'self.x' not initialized at super.init call super.init() } }
A simple fix for this is to change the property definition to
var x = 0, or to explicitly assign to it before callingsuper.init(). -
Relatedly, the compiler now diagnoses incorrect calls to
super.init(). It validates that any path through an initializer callssuper.init()exactly once, that all ivars are defined before the call to super.init, and that any uses which require the entire object to be initialized come after thesuper.initcall. -
Type checker performance has improved considerably (but we still have much work to do here).
- The "slice" versus "array" subtlety is now dead.
Slice<T>has been folded intoArray<T>andT[]is just sugar forArray<T>.
-
Unreachable code warning has been added:
var y: Int = 1 if y == 1 { // note: condition always evaluates to true return y } return 1 // warning: will never be executed
-
Overflows on integer type conversions are now detected at runtime and, when dealing with constants, at compile time:
var i: Int = -129 var i8 = Int8(i) // error: integer overflows when converted from 'Int' to 'Int8' var si = Int8(-1) var ui = UInt8(si) // error: negative integer cannot be converted to unsigned type 'UInt8'
-
defkeyword was changed back tofunc.
-
Objective-C-compatible protocols can now contain optional requirements, indicated by the
@optionalattribute:@class_protocol @objc protocol NSWobbling { @optional def wobble() }
A class that conforms to the
NSWobblingprotocol above can (but does not have to) implementwobble. When referring to thewobblemethod for a value of typeNSWobbling(or a value of generic type that is bounded byNSWobbling), the result is an optional value indicating whether the underlying object actually responds to the given selector, using the same mechanism as messagingid. One can use!to assume that the method is always there,?to chain the optional, or conditional branches to handle each case distinctly:def tryToWobble(w : NSWobbling) { w.wobble() // error: cannot call a value of optional type w.wobble!() // okay: calls -wobble, but fails at runtime if not there w.wobble?() // okay: calls -wobble only if it's there, otherwise no-op if w.wobble { // okay: we know -wobble is there } else { // okay: we know -wobble is not there } }
-
Enums from Cocoa that are declared with the
NS_ENUMmacro are now imported into Swift as Swift enums. Like all Swift enums, the constants of the Cocoa enum are scoped as members of the enum type, so the importer strips off the common prefix of all of the constant names in the enum when forming the Swift interface. For example, this Objective-C declaration:typedef NS_ENUM(NSInteger, NSComparisonResult) { NSOrderedAscending, NSOrderedSame, NSOrderedDescending, };
shows up in Swift as:
enum NSComparisonResult : Int { case Ascending, Same, Descending }
The
enumcases can then take advantage of type inference from context. In Objective-C, you would write:NSNumber *foo = [NSNumber numberWithInt: 1]; NSNumber *bar = [NSNumber numberWithInt: 2]; switch ([foo compare: bar]) { case NSOrderedAscending: NSLog(@"ascending\n"); break; case NSOrderedSame: NSLog(@"same\n"); break; case NSOrderedDescending: NSLog(@"descending\n"); break; }
In Swift, this becomes:
var foo: NSNumber = 1 var bar: NSNumber = 2 switch foo.compare(bar) { case .Ascending: println("ascending") case .Same: println("same") case .Descending: println("descending") }
-
Work has begun on implementing static properties. Currently they are supported for nongeneric structs and enums.
struct Foo { static var foo: Int = 2 } enum Bar { static var bar: Int = 3 } println(Foo.foo) println(Bar.bar)
-
funckeyword was changed todef. -
Implicit conversions are now allowed from an optional type
T?to another optional typeU?ifTis implicitly convertible toU. For example, optional subclasses convert to their optional base classes:class Base {} class Derived : Base {} var d: Derived? = Derived() var b: Base? = d
-
Type inference for variables has been improved, allowing any variable to have its type inferred from its initializer, including global and instance variables:
class MyClass { var size = 0 // inferred to Int } var name = "Swift"
Additionally, the arguments of a generic type can also be inferred from the initializer:
// infers Dictionary<String, Int> var dict: Dictionary = ["Hello": 1, "World": 2]
-
Missing return statement from a non-
Voidfunction is diagnosed as an error. -
Vector<T>has been replaced withArray<T>. This is a complete rewrite to use value-semantics and copy-on-write behavior. The former means that you never need to defensively copy again (or remember to attribute a property as "copy") and the latter yields better performance than defensive copying.Dictionary<T>is next. -
switchcan now pattern-match into structs and classes, using the syntaxcase Type(property1: pattern1, property2: pattern2, ...):.struct Point { var x, y: Double } struct Size { var w, h: Double } struct Rect { var origin: Point; var size: Size } var square = Rect(Point(0, 0), Size(10, 10)) switch square { case Rect(size: Size(w: var w, h: var h)) where w == h: println("square") case Rect(size: Size(w: var w, h: var h)) where w > h: println("long rectangle") default: println("tall rectangle") }
Currently only stored properties ("ivars" in ObjC terminology) are supported by the implementation.
-
Array and dictionary literals allow an optional trailing comma:
var a = [ 1, 2, ] var d = [ "a": 1, "b": 2, ]
-
Unlike in Objective-C, objects of type
idin Swift do not implicitly convert to any class type. For example, the following code is ill-formed:func getContentViewBounds(window : NSWindow) -> NSRect { var view : NSView = window.contentView() // error: 'id' doesn't implicitly convert to NSView return view.bounds() }
because
contentView()returns anid. One can now use the postfix!operator to allow an object of typeidto convert to any class type, e.g.,func getContentViewBounds(window : NSWindow) -> NSRect { var view : NSView = window.contentView()! // ok: checked conversion to NSView return view.bounds() }
The conversion is checked at run-time, and the program will fail if the object is not an NSView. This is shorthand for
var view : NSView = (window.contentView() as NSView)!
which checks whether the content view is an
NSView(via theas NSView). That operation returns an optionalNSView(writtenNSView?) and the!operation assumes that the cast succeeded, i.e., that the optional has a value in it. -
The unconditional checked cast syntax
x as! Thas been removed. Many cases where conversion fromidis necessary can now be handled by postfix!(see above). Fully general unconditional casts can still be expressed usingasand postfix!together,(x as T)!. -
The old "square bracket" attribute syntax has been removed.
-
Overflows on construction of integer and floating point values from integer literals that are too large to fit the type are now reported by the compiler. Here are some examples:
var x = Int8(-129) // error: integer literal overflows when stored into 'Int8' var y : Int = 0xFFFF_FFFF_FFFF_FFFF_F // error: integer literal overflows when stored into 'Int'
Overflows in constant integer expressions are also reported by the compiler.
var x : Int8 = 125 var y : Int8 = x + 125 // error: arithmetic operation '125 + 125' (on type 'Int8') results in // an overflow
-
Division by zero in constant expressions is now detected by the compiler:
var z: Int = 0 var x = 5 / z // error: division by zero
-
Generic structs with type parameters as field types are now fully supported.
struct Pair<T, U> { var first: T var second: U }
-
Autorelease pools can now be created using the
autoreleasepoolfunction.autoreleasepool { // code }
Note that the wrapped code is a closure, so constructs like
breakandcontinueandreturndo not behave as they would inside an Objective-C@autoreleasepoolstatement. -
Enums can now declare a "raw type", and cases can declare "raw values", similar to the integer underlying type of C enums:
// Declare the underlying type as in Objective-C or C++11, with // ': Type' enum AreaCode : Int { // Assign explicit values to cases with '=' case SanFrancisco = 415 case EastBay = 510 case Peninsula = 650 case SanJose = 408 // Values are also assignable by implicit auto-increment case Galveston // = 409 case Baltimore // = 410 }
This introduces
fromRawandtoRawmethods on the enum to perform conversions from and to the raw type:/* As if declared: extension AreaCode { // Take a raw value, and produce the corresponding enum value, // or None if there is no corresponding enum value static func fromRaw(raw:Int) -> AreaCode? // Return the corresponding raw value for 'self' func toRaw() -> Int } */ AreaCode.fromRaw(415) // => .Some(.SanFrancisco) AreaCode.fromRaw(111) // => .None AreaCode.SanJose.toRaw() // => 408Raw types are not limited to integer types--they can additionally be character, floating-point, or string values:
enum State : String { case CA = "California" case OR = "Oregon" case WA = "Washington" } enum SquareRootOfInteger : Float { case One = 1.0 case Two = 1.414 case Three = 1.732 case Four = 2.0 }
Raw types are currently limited to simple C-like enums with no payload cases. The raw values are currently restricted to simple literal values; expressions such as
1 + 1or references to other enum cases are not yet supported. Raw values are also currently required to be unique for each case in an enum.Enums with raw types implicitly conform to the
RawRepresentableprotocol, which exposes the fromRaw and toRaw methods to generics:protocol RawRepresentable { typealias RawType static func fromRaw(raw: RawType) -> Self? func toRaw() -> RawType }
-
Attribute syntax has been redesigned (see (rdar://10700853) and (rdar://14462729)) so that attributes now preceed the declaration and use the
@character to signify them. Where before you might have written:func [someattribute=42] foo(a : Int) {}
you now write:
@someattribute=42 func foo(a : Int) {}
This flows a lot better (attributes don't push the name for declarations away), and means that square brackets are only used for array types, collection literals, and subscripting operations.
-
The
forloop now uses the Generator protocol instead of theEnumeratorprotocol to iterate a sequence. This protocol looks like this:protocol Generator { typealias Element func next() -> Element? }
The single method
next()advances the generator and returns an Optional, which is either.Some(value), wrapping the next value out of the underlying sequence, or.Noneto signal that there are no more elements. This is an improvement over the previous Enumerator protocol because it eliminates the separateisEmpty()query and better reflects the semantics of ephemeral sequences like un-buffered input streams.
-
The
[byref]attribute has been renamed to[inout]. When applied to a logical property, the getter is invoked before a call and the setter is applied to write back the result.inoutconveys this better and aligns with existing Objective-C practice better. -
[inout]arguments can now be captured into closures. The semantics of a inout capture are that the captured variable is an independent local variable of the callee, and the inout is updated to contain the value of that local variable at function exit.In the common case, most closure arguments do not outlive the duration of their callee, and the observable behavior is unchanged. However, if the captured variable outlives the function, you can observe this. For example, this code:
func foo(x : [inout] Int) -> () -> Int { func bar() -> Int { x += 1 return x } // Call 'bar' once while the inout is active. bar() return bar } var x = 219 var f = foo(&x) // x is updated to the value of foo's local x at function exit. println("global x = \(x)") // These calls only update the captured local 'x', which is now independent // of the inout parameter. println("local x = \(f())") println("local x = \(f())") println("local x = \(f())") println("global x = \(x)")
will print:
global x = 220 local x = 221 local x = 222 local x = 223 global x = 220In no case will you end up with a dangling pointer or other unsafe construct.
-
x as Tnow performs a checked cast toT?, producing.Some(t)if the cast succeeds, or.Noneif the cast fails. -
The ternary expression (
x ? y : z) now requires whitespace between the first expression and the question mark. This permits?to be used as a postfix operator. -
A significant new piece of syntactic sugar has been added to ease working with optional values. The
?postfix operator is analogous to!, but instead of asserting on None, it causes all the following postfix operators to get skipped and returnNone.In a sense, this generalizes (and makes explicit) the Objective-C behavior where message sends to
nilsilently produce the zero value of the result.For example, this code
object?.parent.notifyChildEvent?(object!, .didExplode)
first checks whether
objecthas a value; if so, it drills to its parent and checks whether that object implements thenotifyChildEventmethod; if so, it calls that method. (Note that we do not yet have generalized optional methods.)This code:
var titleLength = object?.title.length
checks whether
objecthas a value and, if so, asks for the length of its title.titleLengthwil have typeInt?, and ifobjectwas missing, the variable will be initialized to None. -
Objects with type
idcan now be used as the receiver of property accesses and subscript operations to get (but not set) values. The result is of optional type. For example, for a variableobjof typeid, the expressionobj[0]
will produce a value of type
id, which will either contain the result of the message send objectAtIndexedSubscript(0) (wrapped in an optional type) or, if the object does not respond toobjectAtIndexedSubscript:, an empty optional. The same approach applies to property accesses. -
_can now be used not only invarbindings, but in assignments as well, to ignore elements of a tuple assignment, or to explicitly ignore values.var a = (1, 2.0, 3) var x = 0, y = 0 _ = a // explicitly load and discard 'a' (x, _, y) = a // assign a.0 to x and a.2 to y
-
The
unionkeyword has been replaced withenum. Unions and enums are semantically identical in swift (the former just has data associated with its discriminators) andenumis the vastly more common case. For more rationale, please see docs/proposals/Enums.rst -
The Optional type
T?is now represented as anenum:enum Optional<T> { case None case Some(T) }
This means that, in addition to the existing Optional APIs, it can be pattern-matched with switch:
var x : X?, y : Y? switch (x, y) { // Both are present case (.Some(var a), .Some(var b)): println("both") // One is present case (.Some, .None): case (.None, .Some): println("one") // Neither is present case (.None, .None): println("neither") }
-
Enums now allow multiple cases to be declared in a comma-separated list in a single
casedeclaration:enum Color { case Red, Green, Blue }
-
The Objective-C
idandClasstypes now support referring to methods declared in any class or protocol without a downcast. For example, given a variablesenderof typeid, one can refer to-isEqual: with:sender.isEqualThe actual object may or may not respond to
-isEqual, so this expression returns result of optional type whose value is determined via a compiler-generated-respondsToSelectorsend. When it succeeds, the optional contains the method; when it fails, the optional is empty.To safely test the optional, one can use, e.g.,
var senderIsEqual = sender.isEqual if senderIsEqual { // this will never trigger an "unrecognized selector" failure var equal = senderIsEqual!(other) } else { // sender does not respond to -isEqual: }
When you know that the method is there, you can use postfix
!to force unwrapping of the optional, e.g.,sender.isEqual!(other)
This will fail at runtime if in fact sender does not respond to
-isEqual:. We have some additional syntactic optimizations planned for testing an optional value and handling both the success and failure cases concisely. Watch this space. -
Weak references now always have optional type. If a weak variable has an explicit type, it must be an optional type:
var [weak] x : NSObject?
If the variable is not explicitly typed, its type will still be inferred to be an optional type.
-
There is now an implicit conversion from
TtoT?.
-
Constructor syntax has been improved to align better with Objective-C's
initmethods. Theconstructorkeyword has been replaced withinit, and the selector style of declaration used for func declarations is now supported. For example:class Y : NSObject { init withInt(i : Int) string(s : String) { super.init() // call superclass initializer } }
One can use this constructor to create a
Yobject with, e.g.,Y(withInt:17, string:"Hello")
Additionally, the rules regarding the selector corresponding to such a declaration have been revised. The selector for the above initializer is
initWithInt:string:; the specific rules are described in the documentation.Finally, Swift initializers now introduce Objective-C entry points, so a declaration such as:
class X : NSObject { init() { super.init() } }
Overrides
NSObject's-initmethod (which it calls first) as well as introducing the 'allocating' entry point so that one can create a newXinstance with the syntaxX(). -
Variables in top-level code (i.e. scripts, but not global variables in libraries) that lack an initializer now work just like local variables: they must be explicitly assigned-to sometime before any use, instead of being default constructed. Instance variables are still on the TODO list.
-
Generic unions with a single payload case and any number of empty cases are now implemented, for example:
union Maybe<T> { case Some(T) case None } union Tristate<T> { case Initialized(T) case Initializing case Uninitialized }
Generic unions with multiple payload cases are still not yet implemented.
-
The implementation now supports partial application of class and struct methods:
(swift) class B { func foo() { println("B") } } (swift) class D : B { func foo() { println("D") } } (swift) var foo = B().foo // foo : () -> () = <unprintable value> (swift) foo() B (swift) foo = D().foo (swift) foo() D
Support for partial application of Objective-C class methods and methods in generic contexts is still incomplete.
-
Local variable declarations without an initializer are no longer implicitly constructed. The compiler now verifies that they are initialized on all paths leading to a use of the variable. This means that constructs like this are now allowed:
var p : SomeProtocol if whatever { p = foo() } else { p = bar() }
where before, the compiler would reject the definition of
psaying that it needed an initializer expression.Since all local variables must be initialized before use, simple things like this are now rejected as well:
var x : Int print(x)
The fix is to initialize the value on all paths, or to explicitly default initialize the value in the declaration, e.g. with
var x = 0or withvar x = Int()(which works for any default-constructible type). -
The implementation now supports unions containing protocol types and weak reference types.
-
The type annotation syntax,
x as T, has been removed from the language. The checked cast operationsx as! Tandx is Tstill remain.
-
thishas been renamed toself. Similarly,Thishas been renamed toSelf. -
Swift now supports unions. Unlike C unions, Swift's
unionis type-safe and always knows what type it contains at runtime. Union members are labeled usingcasedeclarations; each case may have a different set of types or no type:union MaybeInt { case Some(Int) case None } union HTMLTag { case A(href:String) case IMG(src:String, alt:String) case BR }
Each
casewith a type defines a static constructor function for the union type.casedeclarations without types become static members:var br = HTMLTag.BR var a = HTMLTag.A(href:"http://www.apple.com/") // 'HTMLTag' scope deduced for '.IMG' from context var img : HTMLTag = .IMG(src:"http://www.apple.com/mac-pro.png", alt:"The new Mac Pro")
Cases can be pattern-matched using
switch:switch tag { case .BR: println("<br>") case .IMG(var src, var alt): println("<img src=\"\(escape(src))\" alt=\"\(escape(alt))\">") case .A(var href): println("<a href=\"\(escape(href))\">") }
Due to implementation limitations, recursive unions are not yet supported.
-
Swift now supports autolinking, so importing frameworks or Swift libraries should no longer require adding linker flags or modifying your project file.
-
Swift now supports weak references by applying the
[weak]attribute to a variable declaration.(swift) var x = NSObject() // x : NSObject = <NSObject: 0x7f95d5804690> (swift) var [weak] w = x // w : NSObject = <NSObject: 0x7f95d5804690> (swift) w == nil // r2 : Bool = false (swift) x = NSObject() (swift) w == nil // r3 : Bool = true
Swift also supports a special form of weak reference, called
[unowned], for references that should never be nil but are required to be weak to break cycles, such as parent or sibling references. Accessing an[unowned]reference asserts that the reference is still valid and implicitly promotes the loaded reference to a strong reference, so it does not need to be loaded and checked for nullness before use like a true[weak]reference.class Parent { var children : Array<Child> func addChild(c:Child) { c.parent = this children.append(c) } } class Child { var [unowned] parent : Parent }
-
Numeric literals can now use underscores as separators. For example:
var billion = 1_000_000_000 var crore = 1_00_00_000 var MAXINT = 0x7FFF_FFFF_FFFF_FFFF var SMALLEST_DENORM = 0x0.0000_0000_0000_1p-1022
-
Types conforming to protocols now must always declare the conformance in their inheritance clause.
-
The build process now produces serialized modules for the standard library, greatly improving build times.
-
Arithmetic operators
+,-,*, and/on integer types now do overflow checking and trap on overflow. A parallel set of masking operators,&+,&-,&*, and&/, are defined to perform two's complement wrapping arithmetic for all signed and unsigned integer types. -
Debugger support. Swift has a
-gcommand line switch that turns on debug info for the compiled output. Using the standard lldb debugger this will allow single-stepping through Swift programs, printing backtraces, and navigating through stack frames; all in sync with the corresponding Swift source code. An unmodified lldb cannot inspect any variables.Example session:
$ echo 'println("Hello World")' >hello.swift $ swift hello.swift -c -g -o hello.o $ ld hello.o "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.9.0" \ -framework Foundation lib/swift/libswift_stdlib_core.dylib \ lib/swift/libswift_stdlib_posix.dylib -lSystem -o hello $ lldb hello Current executable set to 'hello' (x86_64). (lldb) b top_level_code Breakpoint 1: where = hello`top_level_code + 26 at hello.swift:1, addre... (lldb) r Process 38592 launched: 'hello' (x86_64) Process 38592 stopped * thread #1: tid = 0x1599fb, 0x0000000100000f2a hello`top_level_code + ... frame #0: 0x0000000100000f2a hello`top_level_code + 26 at hello.shi... -> 1 println("Hello World") (lldb) bt * thread #1: tid = 0x1599fb, 0x0000000100000f2a hello`top_level_code + ... frame #0: 0x0000000100000f2a hello`top_level_code + 26 at hello.shi... frame #1: 0x0000000100000f5c hello`main + 28 frame #2: 0x00007fff918605fd libdyld.dylib`start + 1 frame #3: 0x00007fff918605fd libdyld.dylib`start + 1Also try
s,n,up,down.
-
Swift now has a
switchstatement, supporting pattern matching of multiple values with variable bindings, guard expressions, and range comparisons. For example:func classifyPoint(point:(Int, Int)) { switch point { case (0, 0): println("origin") case (_, 0): println("on the x axis") case (0, _): println("on the y axis") case (var x, var y) where x == y: println("on the y = x diagonal") case (var x, var y) where -x == y: println("on the y = -x diagonal") case (-10..10, -10..10): println("close to the origin") case (var x, var y): println("length \(sqrt(x*x + y*y))") } }
-
Swift has a new closure syntax. The new syntax eliminates the use of pipes. Instead, the closure signature is written the same way as a function type and is separated from the body by the
inkeyword. For example:sort(fruits) { (lhs : String, rhs : String) -> Bool in return lhs > rhs }
When the types are omitted, one can also omit the parentheses, e.g.,
sort(fruits) { lhs, rhs in lhs > rhs }
Closures with no parameters or that use the anonymous parameters (
$0,$1, etc.) don't need thein, e.g.,sort(fruits) { $0 > $1 }
-
nilcan now be used without explicit casting. Previously,nilhad typeNSObject, so one would have to write (e.g.)nil as! NSArrayto create anilNSArray. Now,nilpicks up the type of its context. -
POSIX.EnvironmentVariablesandswift.CommandLineArgumentsglobal variables were merged into aswift.Processvariable. Now you can access command line arguments withProcess.arguments. In order to acces environment variables addimport POSIXand useProcess.environmentVariables.