Swift (programming language)
Swift is a high-level general-purpose, multi-paradigm, compiled programming language developed by Apple Inc. and the open-source community. Swift compiles to machine code, as it is an LLVM-based compiler. Swift was first released in June 2014,[10] and the Swift toolchain has shipped in Xcode since version 6, released in 2014.
Paradigm | Multi-paradigm: protocol-oriented, object-oriented, functional, imperative, block structured, declarative, concurrent |
---|---|
Designed by | Chris Lattner, Doug Gregor, John McCall, Ted Kremenek, Joe Groff, and Apple Inc.[1] |
Developer | Apple Inc. and open-source contributors |
First appeared | June 2, 2014[2] |
Stable release | 5.9.1[3]
/ 19 October 2023 |
Preview release | 5.9
|
Typing discipline | Static, strong, inferred |
Memory management | Automatic Reference Counting |
OS | Apple's operating systems (Darwin, iOS, iPadOS, macOS, tvOS, watchOS), Linux, Windows 10, Android |
License | Apache License 2.0 (Swift 2.2 and later) Proprietary (up to Swift 2.2)[4][5] |
Filename extensions | .swift, .SWIFT |
Website | |
Influenced by | |
Objective-C,[6] Rust, Haskell, Ruby, Python, C#, CLU,[7] D[8] | |
Influenced | |
Rust[9] |
Apple intended Swift to support many core concepts associated with Objective-C, notably dynamic dispatch, widespread late binding, extensible programming and similar features, but in a "safer" way, making it easier to catch software bugs; Swift has features addressing some common programming errors like null pointer dereferencing and provides syntactic sugar to help avoid the pyramid of doom. Swift supports the concept of protocol extensibility, an extensibility system that can be applied to types, structs and classes, which Apple promotes as a real change in programming paradigms they term "protocol-oriented programming"[11] (similar to traits and type classes).[12]
Swift was introduced at Apple's 2014 Worldwide Developers Conference (WWDC).[13] It underwent an upgrade to version 1.2 during 2014 and a major upgrade to Swift 2 at WWDC 2015. Initially a proprietary language, version 2.2 was made open-source software under the Apache License 2.0 on December 3, 2015, for Apple's platforms and Linux.[14][15]
Through version 3.0 the syntax of Swift went through significant evolution, with the core team making source stability a focus in later versions.[16][17] In the first quarter of 2018 Swift surpassed Objective-C in measured popularity.[18]
Swift 4.0, released in 2017, introduced several changes to some built-in classes and structures. Code written with previous versions of Swift can be updated using the migration functionality built into Xcode. Swift 5, released in March 2019, introduced a stable binary interface on Apple platforms, allowing the Swift runtime to be incorporated into Apple operating systems. It is source compatible with Swift 4.[19]
Swift 5.1 was officially released in September 2019. Swift 5.1 builds on the previous version of Swift 5 by extending the stable features of the language to compile-time with the introduction of module stability. The introduction of module stability makes it possible to create and share binary frameworks that will work with future releases of Swift.[20]
Swift 5.5, officially announced by Apple at the 2021 WWDC, significantly expands language support for concurrency and asynchronous code, notably introducing a unique version of the actor model.[21]
The current version, Swift 5.9, was released in September 2023 and includes a macro system, generic parameter packs, and ownership features like the new consume
operator.[22]
History
Development of Swift started in July 2010 by Chris Lattner, with the eventual collaboration of many other programmers at Apple. Swift was motivated by the need for a replacement for Apple's earlier programming language Objective-C, which had been largely unchanged since the early 1980s and lacked modern language features. Swift took language ideas "from Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, and far too many others to list".[7] On June 2, 2014, the Apple Worldwide Developers Conference (WWDC) application became the first publicly released app written with Swift.[23] A beta version of the programming language was released to registered Apple developers at the conference, but the company did not promise that the final version of Swift would be source code compatible with the test version. Apple planned to make source code converters available if needed for the full release.[23]
The Swift Programming Language, a free 500-page manual, was also released at WWDC, and is available on the Apple Books Store and the official website.[24]
Swift reached the 1.0 milestone on September 9, 2014, with the Gold Master of Xcode 6.0 for iOS.[25] Swift 1.1 was released on October 22, 2014, alongside the launch of Xcode 6.1.[26] Swift 1.2 was released on April 8, 2015, along with Xcode 6.3.[27] Swift 2.0 was announced at WWDC 2015, and was made available for publishing apps in the App Store on September 21, 2015.[28] Swift 3.0 was released on September 13, 2016.[29] Swift 4.0 was released on September 19, 2017.[30] Swift 4.1 was released on March 29, 2018.[31]
Swift won first place for Most Loved Programming Language in the Stack Overflow Developer Survey 2015[32] and second place in 2016.[33]
On December 3, 2015, the Swift language, supporting libraries, debugger, and package manager were open-sourced under the Apache 2.0 license with a Runtime Library Exception,[34] and Swift.org was created to host the project. The source code is hosted on GitHub, where it is easy for anyone to get the code, build it themselves, and even create pull requests to contribute code back to the project.
In December 2015, IBM announced its Swift Sandbox website, which allows developers to write Swift code in one pane and display output in another.[35][36][37] The Swift Sandbox was deprecated in January 2018.[38]
During the WWDC 2016, Apple announced an iPad exclusive app, named Swift Playgrounds, intended to teach people how to code in Swift. The app is presented in a 3D video game-like interface which provides feedback when lines of code are placed in a certain order and executed.[39][40][41]
In January 2017, Chris Lattner announced his departure from Apple for a new position with Tesla Motors, with the Swift project lead role going to team veteran Ted Kremenek.[42][43]
During WWDC 2019, Apple announced SwiftUI with Xcode 11, which provides a framework for declarative UI structure design across all Apple platforms.[44]
Official downloads for the Ubuntu distribution of Linux have been available since Swift 2.2, with more distros added since Swift 5.2.4, CentOS and Amazon Linux.[45] There is an unofficial SDK and native toolchain package for Android too.[46][47]
Platforms
The platforms Swift supports are Apple's operating systems (Darwin, iOS, iPadOS, macOS, tvOS, watchOS), Linux, Windows, and Android.[48][49]
A key aspect of Swift's design is its ability to interoperate with the huge body of existing Objective-C code developed for Apple products over the previous decades, such as Cocoa and the Cocoa Touch frameworks. On Apple platforms,[50] it links with the Objective-C runtime library, which allows C, Objective-C, C++ and Swift code to run within one program.[51]
Version history
Version | Release Date | macOS | Linux | Windows |
---|---|---|---|---|
Swift 1.0 | September 9, 2014 | Yes | No | No |
Swift 1.1 | October 22, 2014 | Yes | No | No |
Swift 1.2 | April 8, 2015 | Yes | No | No |
Swift 2.0 | September 21, 2015 | Yes | No | No |
Swift 2.1 | October 20, 2015 | Yes | No | No |
Swift 2.2 | March 21, 2016 | Yes | Yes | No |
Swift 2.2.1 | May 3, 2016 | Yes | Yes | No |
Swift 3.0 | September 13, 2016 | Yes | Yes | No |
Swift 3.0.1 | October 28, 2016 | Yes | Yes | No |
Swift 3.0.2 | December 13, 2016 | Yes | Yes | No |
Swift 3.1 | March 27, 2017 | Yes | Yes | No |
Swift 3.1.1 | April 21, 2017 | Yes | Yes | No |
Swift 4.0 | September 19, 2017 | Yes | Yes | No |
Swift 4.0.2 | November 1, 2017 | Yes | Yes | No |
Swift 4.0.3 | December 5, 2017 | Yes | Yes | No |
Swift 4.1 | March 29, 2018 | Yes | Yes | No |
Swift 4.1.1 | May 4, 2018 | No | Yes | No |
Swift 4.1.2 | May 31, 2018 | Yes | Yes | No |
Swift 4.1.3 | July 27, 2018 | No | Yes | No |
Swift 4.2 | September 17, 2018 | Yes | Yes | No |
Swift 4.2.1 | October 30, 2018 | Yes | Yes | No |
Swift 4.2.2 | February 4, 2019 | No | Yes | No |
Swift 4.2.3 | February 28, 2019 | No | Yes | No |
Swift 4.2.4 | March 29, 2019 | No | Yes | No |
Swift 5.0[52] | March 25, 2019 | Yes | Yes | No |
Swift 5.0.1 | April 18, 2019 | Yes | Yes | No |
Swift 5.0.2 | July 15, 2019 | No | Yes | No |
Swift 5.0.3 | August 30, 2019 | No | Yes | No |
Swift 5.1 | September 10, 2019 | Yes | Yes | No |
Swift 5.1.1 | October 11, 2019 | No | Yes | No |
Swift 5.1.2 | November 7, 2019 | Yes | Yes | No |
Swift 5.1.3 | December 13, 2019 | Yes | Yes | No |
Swift 5.1.4 | January 31, 2020 | No | Yes | No |
Swift 5.1.5 | March 9, 2020 | No | Yes | No |
Swift 5.2 | March 24, 2020 | Yes | Yes | No |
Swift 5.2.1 | March 30, 2020 | No | Yes | No |
Swift 5.2.2 | April 15, 2020 | Yes | Yes | No |
Swift 5.2.3 | April 29, 2020 | No | Yes | No |
Swift 5.2.4 | May 20, 2020 | Yes | Yes | No |
Swift 5.2.5 | August 5, 2020 | No | Yes | No |
Swift 5.3 | September 16, 2020 | Yes | Yes | Yes[53] |
Swift 5.3.1 | November 13, 2020 | Yes | Yes | Yes |
Swift 5.3.2 | December 15, 2020 | Yes | Yes | Yes |
Swift 5.3.3 | January 25, 2021 | No | Yes | Yes |
Swift 5.4[54] | April 26, 2021 | Yes | Yes | Yes |
Swift 5.4.1 | May 25, 2021 | No | Yes | Yes |
Swift 5.4.2 | June 28, 2021 | Yes | Yes | Yes |
Swift 5.4.3 | September 9, 2021 | No | Yes | Yes |
Swift 5.5 | September 20, 2021 | Yes | Yes | Yes |
Swift 5.5.1 | October 27, 2021 | Yes | Yes | Yes |
Swift 5.5.2 | December 14, 2021 | Yes | Yes | Yes |
Swift 5.5.3 | February 9, 2022 | No | Yes | Yes |
Swift 5.6[55] | March 14, 2022 | Yes | Yes | Yes |
Swift 5.6.1[56] | April 9, 2022 | No | Yes | Yes |
Swift 5.6.2[57] | June 15, 2022 | No | Yes | Yes |
Swift 5.6.3[58] | September 2, 2022 | No | Yes | Yes |
Swift 5.7[59] | September 12, 2022 | Yes | Yes | Yes |
Swift 5.7.1[60] | November 1, 2022 | Yes | Yes | Yes |
Swift 5.8[61] | March 30, 2023 | Yes | Yes | Yes |
Swift 5.8.1[62] | June 1, 2023 | Yes | Yes | Yes |
Swift 5.9[63] | September 18, 2023 | Yes | Yes | Yes |
Features
Swift is an alternative to the Objective-C language that employs modern programming-language theory concepts and strives to present a simpler syntax. During its introduction, it was described simply as "Objective-C without the baggage of C".[64][65]
By default, Swift does not expose pointers and other unsafe accessors, in contrast to Objective-C, which uses pointers pervasively to refer to object instances. Also, Objective-C's use of a Smalltalk-like syntax for making method calls has been replaced with a dot-notation style and namespace system more familiar to programmers from other common object-oriented (OO) languages like Java or C#. Swift introduces true named parameters and retains key Objective-C concepts, including protocols, closures and categories, often replacing former syntax with cleaner versions and allowing these concepts to be applied to other language structures, like enumerated types (enums).[66]
Basic Syntax
Swift's syntax is similar to C-style languages. Code begins executing in the global scope by default.[67] Alternatively, the @main
attribute can be applied a structure, class, or enumeration declaration to indicate that it contains the program's entry point.[68]
Swift's "Hello, World!" program is:
print("Hello, world!")
The print(_:separator:terminator:)
function used here is included in Swift's standard library, which is available to all programs without the need to import external modules. Statements in Swift don't have to end with a semicolon, however semicolons are required to separate multiple statements written on the same line. Single-line comments being with //
and continue until the end of the current line. Multiline comments are contained by /*
and */
characters.
Constants are declared with the let
keyword and variables with the var
keyword. Values must be initialized before they are read. Values may infer their type based on the type of the provided initial value. If the initial value is set after the value's declaration, a type must be declared explicitly.[69]
let highScoreThreshold = 1000 // A constant with type Int. The type was inferred based on the provided value.
var currentScore = 980 // A variable with type Int.
currentScore = 1200 // The value of variables can change over time.
let playerMessage: String // A constant with explicit type String.
if currentScore > highScoreThreshold {
playerMessage = "You are a top player!"
} else {
playerMessage = "Better luck next time."
}
print(playerMessage) // Prints "You are a top player!"
Control flow in Swift is managed with if-else, guard, and switch statements, along with while and for-in loops.
If statements take a boolean parameter and execute the body of the if statement if the condition is true, otherwise it executes the optional else
body. if-let
syntax provides syntactic sugar for checking for the existence of an optional value, and unwrapping it at the same time.
let someNumber = 42
if someNumber % 2 == 0 { // Use the modulo operator to find the remainder of someNumber divided by 2.
print("\(someNumber) is even.")
} else{
print("\(someNumber) is odd.")
}
// Prints "42 is even."
statements require that the given condition is true before continuing on past the guard statement, otherwise the body of the provided else
clause is run. The else
clause must exit control of the code block in which the else
statement appears. else
statements are useful for ensuring that certain requirements are met before continuing on with program execution. In particular they can be used to create an unwrapped version of an optional value that is guaranteed to be non-nil for the remainder of the enclosing scope.else
func divide(numerator: Int?, byDenominator denominator: Int) -> Int? {
guard denominator != 0 else {
print("Can't divide by 0.")
return nil
}
guard let numerator else {
print("The provided numerator is nil.")
return nil
}
return numerator / denominator
}
let result = divide(numerator: 3, byDenominator: 0)
print("Division result is: \(result)")
// Prints:
// "Can't divide by 0."
// "Result is nil."
switch
statements compares a value with multiple potential values. switch
statements must be made exhaustive, either by including cases for all possible values or by including a default
case which is run when the provided value doesn't match any of the other cases. switch
cases do not implicitly fall through, although they may explicitly do so with the fallthrough
keyword. Pattern matching can be used in various ways inside switch
statements. Here is an example of an integer being matched against a number of potential ranges:
let someNumber = 42
switch someNumber {
case ..<0:
print("\(someNumber) negative.")
case 0:
print("\(someNumber) is 0.")
case 1...9:
print("\(someNumber) greater than 0, but less than 10.")
default:
print("\(someNumber) is greater than 9.")
}
// Prints "42 is greater than 9."
for-in
loops iterate over a sequence of values:
let names = ["Will", "Anna", "Bart"]
for name in names {
print(name)
}
// Prints:
// Will
// Anna
// Bart
while
loops iterate as long as the given boolean condition evaluates to true
.
// Add together all the numbers from 1 to 5.
var i = 1
var result = 0
while i <= 5 { // The loop performs its body as long as i is less than or equal to 5.
result += i // Add i to the current result.
i += 1 // Increment i by 1.
}
print(result) // Prints "15"
Closure support
Swift supports closures, which are self-contained blocks of functionality that can be passed around and used in code,[70] and can also be used as anonymous functions. Here are some examples:
// Closure type, defined by its input and output values, can be specified outside the closure:
let closure1: (Int, Int) -> Int = { arg1, arg2 in
return arg1 + arg2
}
// …or inside it:
let closure2 = { (arg1: Int, arg2: Int) -> Int in
return arg1 + arg2
}
// In most cases, closure's return type can be inferred automatically by the compiler.
// However, this functionality may not work for too complex expressions.
let closure3 = { arg1: Int, arg2: Int in
return arg1 + arg2
}
Closures can be assigned to variables and constants, and can be passed into other functions or closures as parameters. Single-expression closures may drop the return
keyword.
Swift also has a trailing closure syntax, which allows the closure to be written after the end of the function call instead of within the function's parameter list. Parentheses can be omitted altogether if the closure is the function's only parameter:
// This function takes a closure which receives no input parameters and returns an integer,
// evaluates it, and uses the closure's return value (an Int) as the function's return value.
func foo(closure bar: () -> Int) -> Int {
return bar()
}
// Without trailing closure syntax:
foo(closure: { return 1 })
// With trailing closure syntax, and implicit return:
foo { 1 }
Starting from version 5.3, Swift supports multiple trailing closures:[71]
// This function passes the return of the first closure as the parameter of the second,
// and returns the second closure's result:
func foo(bar: () -> Int, baz: (Int) -> Int) -> Int {
return baz(bar())
}
// With no trailing closures:
foo(bar: { return 1 }, baz: { x in return x + 1 })
// With 1 trailing closure:
foo(bar: { return 1 }) { x in return x + 1 }
// With 2 trailing closures (note that only the first closure's argument name is omitted):
foo { return 1 } baz: { x in return x + 1 }
Swift will provide shorthand argument names for inline closures, removing the need to explicitly name all of the closures parameters.[72] Arguments can be referred to with the names $0, $1, $2, and so on:
let names = ["Josephine", "Steve", "Chris", "Barbara"]
// filter calls the given closure for each value in names.
// Values with a character count less than 6 are kept, the others are dropped.
let shortNames = names.filter { $0.count < 6 }
print(shortNames) // Prints "["Steve", "Chris"]"
Closures may capture values from their surrounding scope. The closure will refer to this captured value for as long as the closure exists:
func makeMultiplier(withMultiple multiple: Int) -> (Int) -> (Int) {
// Create and return a closure that takes in an Int and returns the input multiplied by the value of multiple.
return {
$0 * multiple
}
}
let multiplier = makeMultiplier(withMultiple: 3)
print(multiplier(3)) // Prints "9"
print(multiplier(10)) // Prints "30"
String support
The Swift standard library includes unicode-compliant String
and Character
types. String values can be initialized with a String literal, a sequence of characters surrounded by double quotation marks. Strings can be concatenated with the +
operator:
var someString = "Hello,"
someString += " world!"
String interpolation allows for the creation of a new string from other values and expressions. Values written between parentheses preceded by a \
will be inserted into the enclosing string literal:[73]
var currentScore = 980
print("Your score is \(currentScore).")
// Prints "Your score is 980."
A for-in loop can be used to iterate over the characters contained in a string:
for character in "Swift" {
print(character)
}
// S
// w
// i
// f
// t
When the Foundation framework is imported Swift invisibly bridges the String type to NSString, the String class commonly used in Objective-C.
Access control
Swift supports five access control levels for symbols: open
, public
, internal
, fileprivate
, and private
. Unlike many object-oriented languages, these access controls ignore inheritance hierarchies: private
indicates that a symbol is accessible only in the immediate scope, fileprivate
indicates it is accessible only from within the file, internal
indicates it is accessible within the containing module, public
indicates it is accessible from any module, and open
(only for classes and their methods) indicates that the class may be subclassed outside of the module.[74]
Optionals and chaining
An important new feature in Swift is option types, which allow references or values to operate in a manner similar to the common pattern in C, where a pointer may refer to a value or may be null. This implies that non-optional types cannot result in a null-pointer error; the compiler can ensure this is not possible.
Optional types are created with the Optional
mechanism—to make an Integer that is nullable, one would use a declaration similar to var optionalInteger: Optional<Int>
. As in C#,[75] Swift also includes syntactic sugar for this, allowing one to indicate a variable is optional by placing a question mark after the type name, var optionalInteger: Int?
.[76] Variables or constants that are marked optional either have a value of the underlying type or are nil
. Optional types wrap the base type, resulting in a different instance. String
and String?
are fundamentally different types, the latter has more in common with Int?
than String
.
To access the value inside, assuming it is not nil, it must be unwrapped to expose the instance inside. This is performed with the !
operator:
let myValue = anOptionalInstance!.someMethod()
In this case, the !
operator unwraps anOptionalInstance
to expose the instance inside, allowing the method call to be made on it. If anOptionalInstance
is nil, a null-pointer error occurs. This can be annoying in practice, so Swift also includes the concept of optional chaining to test whether the instance is nil and then unwrap it if it is non-null:
let myValue = anOptionalInstance?.someMethod()
In this case the runtime calls someMethod
only if anOptionalInstance
is not nil, suppressing the error. Normally this requires the programmer to test whether myValue
is nil before proceeding. The origin of the term chaining comes from the more common case where several method calls/getters are chained together. For instance:
let aTenant = aBuilding.tenantList[5]
let theirLease = aTenant.leaseDetails
let leaseStart = theirLease?.startDate
can be reduced to:
let leaseStart = aBuilding.tenantList[5].leaseDetails?.startDate
The ?
syntax circumvents the pyramid of doom.
Objective-C was weakly typed and allowed any method to be called on any object at any time. If the method call failed, there was a default handler in the runtime that returned nil. That meant that no unwrapping or testing was needed, the equivalent statement in Objective-C:
leaseStart = [[[aBuilding tenantList:5] leaseDetails] startDate]
Would return nil, and this could be tested. However, this also demanded that all method calls be dynamic, which introduces significant overhead. Swift's use of optionals provides a similar mechanism for testing and dealing with nils, but does so in a way that allows the compiler to use static dispatch because the unwrapping action is called on a defined instance (the wrapper), versus occurring in the runtime dispatch system.
Value types
In many object-oriented languages, objects are represented internally in two parts. The object is stored as a block of data placed on the heap, while the name (or "handle") to that object is represented by a pointer. Objects are passed between methods by copying the value of the pointer, allowing the same underlying data on the heap to be accessed by anyone with a copy. In contrast, basic types like integers and floating-point values are represented directly; the handle contains the data, not a pointer to it, and that data is passed directly to methods by copying. These styles of access are termed pass-by-reference in the case of objects, and pass-by-value for basic types.
Both concepts have their advantages and disadvantages. Objects are useful when the data is large, like the description of a window or the contents of a document. In these cases, access to that data is provided by copying a 32- or 64-bit value, versus copying an entire data structure. However, smaller values like integers are the same size as pointers (typically both are one word), so there is no advantage to passing a pointer, versus passing the value. Also, pass-by-reference inherently requires a dereferencing operation, which can produce noticeable overhead in some operations, typically those used with these basic value types, like mathematics.
Similarly to C# and in contrast to most other OO languages, Swift offers built-in support for objects using either pass-by-reference or pass-by-value semantics, the former using the class
declaration and the latter using struct
. Structs in Swift have almost all the same features as classes: methods, implementing protocols and using the extension mechanisms. For this reason, Apple terms all data generically as instances, versus objects or values. Structs do not support inheritance, however.[77]
The programmer is free to choose which semantics are more appropriate for each data structure in the application. Larger structures like windows would be defined as classes, allowing them to be passed around as pointers. Smaller structures, like a 2D point, can be defined as structs, which will be pass-by-value and allow direct access to their internal data with no dereference. The performance improvement inherent to the pass-by-value concept is such that Swift uses these types for almost all common data types, including Int
and Double
, and types normally represented by objects, like String
and Array
.[77] Using value types can result in significant performance improvements in user applications as well.[78]
To ensure that even the largest structs do not cause a performance penalty when they are handed off, Swift uses copy on write so that the objects are copied only if and when the program attempts to change a value in them. This means that the various accessors have what is in effect a pointer to the same data storage. So while the data is physically stored as one instance in memory, at the level of the application, these values are separate and physical separation is enforced by copy on write only if needed.[79]
Protocol-oriented programming
A key feature of Objective-C is its support for categories, methods that can be added to extend classes at runtime. Categories allow extending classes in-place to add new functions with no need to subclass or even have access to the original source code. An example might be to add spell checker support to the base NSString
class, which means all instances of NSString in the application gain spell checking. The system is also widely used as an organizational technique, allowing related code to be gathered into library-like extensions. Swift continues to support this concept, although they are now termed extensions, and declared with the keyword extension
. Unlike Objective-C, Swift can also add new properties accessors, types, and enums to extant instances .
Another key feature of Objective-C is its use of protocols, known in most modern languages as interfaces. Protocols promise that a particular class implements a set of methods, meaning that other objects in the system can call those methods on any object supporting that protocol. This is often used in modern OO languages as a substitute for multiple inheritance, although the feature sets are not entirely similar. A common example of a protocol in Cocoa is the NSCopying
protocol, which defines one method, copyWithZone
, that implements deep copying on objects.[80]
In Objective-C, and most other languages implementing the protocol concept, it is up to the programmer to ensure that the required methods are implemented in each class.[81] Swift adds the ability to add these methods using extensions, and to use generic programming (generics) to implement them. Combined, these allow protocols to be written once and support a wide variety of instances. Also, the extension mechanism can be used to add protocol conformance to an object that does not list that protocol in its definition.[80]
For example, a protocol might be declared called StringConvertible
, which ensures that instances that conform to the protocol implement a toString
method that returns a String
. In Swift, this can be declared with code like this:
protocol StringConvertible {
func toString() -> String
}
This protocol can now be added to String, without modifying the base class's source code:
extension String: StringConvertible {
func toString() -> String {
self
}
}
In Swift, like many modern languages supporting interfaces, protocols can be used as types, which means variables and methods can be defined by protocol instead of their specific type:
var someSortOfPrintableObject: StringConvertible
...
print(someSortOfPrintableObject.toString())
It does not matter what sort of instance someSortOfPrintableObject
is, the compiler will ensure that it conforms to the protocol and thus this code is safe. This syntax also means that collections can be based on protocols also, like let printableArray = [StringConvertible]
.
As Swift treats structs and classes as similar concepts, both extensions and protocols are extensively used in Swift's runtime to provide a rich API based on structs. For instance, Swift uses an extension to add the Equatable
protocol to many of their basic types, like Strings and Arrays, allowing them to be compared with the ==
operator. A concrete example of how all of these features interact can be seen in the concept of default protocol implementations:
func !=<T : Equatable>(lhs: T, rhs: T) -> Bool
This function defines a method that works on any instance conforming to Equatable
, providing a not equals function. Any instance, class or struct, automatically gains this implementation simply by conforming to Equatable
. As many instances gain Equatable
through their base implementations or other generic extensions, most basic objects in the runtime gain equals and not equals with no code.[82]
This combination of protocols, defaults, protocol inheritance, and extensions allows many of the functions normally associated with classes and inheritance to be implemented on value types.[80] This concept is widely used within the Swift toolchain itself; in Swift 5.9, approximately 1.2 percent of all symbols within the standard library were protocols, and another 8.6 percent were protocol requirements.[83] Some in Apple have begun calling it a protocol-oriented programming language. They suggest addressing many of the problem domains normally solved through classes and inheritance by instead using structs and protocols.
Concurrency
Swift 5.5 introduced structured concurrency into the language.[84] Structured concurreny uses Async/await syntax similar to Kotlin, JavaScript, and Rust. An async function is defined with the async
keyword after the parameter list. When calling an async function the await
keyword must be written before the function to indicate that execution will potentially suspend while calling function. While a function is suspended the program may run some other concurrent function in the same program. This syntax allows programs to clearly call out potential suspension points and avoid a version of the Pyramid of doom (programming) caused by the previously widespread use of closure callbacks.[85]
func downloadText(name: String) async -> String {
let result = // ... some asynchronous downloading code ...
return result
}
let text = await downloadText("text1")
The async-let
syntax allows multiple functions to run in parallel. await
is again used to mark the point at which the program will suspend to wait for the completion of the async
functions called earlier.
// Each of these calls to downloadText will run in parallel.
async let text1 = downloadText(name: "text1")
async let text2 = downloadText(name: "text2")
async let text3 = downloadText(name: "text3")
let textToPrint = await [text1, text2, text3] // Suspends until all three downloadText calls have returned.
print(textToPrint)
Tasks and TaskGroups can be created explicitly to create a dynamic number of child tasks during runtime:
let taskHandle = Task {
await downloadText(name: "someText")
}
let result = await taskHandle.value
Swift uses the Actor model to isolate mutable state, allowing different tasks to mutate shared state in a safe manner. Actors are declared with the actor
keyword and are reference types, like classes. Only one task may access the mutable state of an actor at the same time. Actors may access and mutate their own internal state freely, but code running in separate tasks must mark each access with the await
keyword to indicate that the code may suspend until other asks finish accessing the actor's state.
actor Directory {
var names: [String] = []
func add(name: String) {
names.append(name)
}
}
let directory = Directory()
// Code suspends until other tasks finish accessing the actor.
await directory.add(name: "Tucker")
print(await directory.names)
Libraries, runtime and development
On Apple systems, Swift uses the same runtime as the extant Objective-C system, but requires iOS 7 or macOS 10.9 or higher. It also depends on Grand Central Dispatch.[86] Swift and Objective-C code can be used in one program, and by extension, C and C++ also. Beginning in Swift 5.9, C++ code can be used directly from Swift code.[87] In the case of Objective-C, Swift has considerable access to the object model, and can be used to subclass, extend and use Objective-C code to provide protocol support.[88] The converse is not true: a Swift class cannot be subclassed in Objective-C.[89]
To aid development of such programs, and the re-use of extant code, Xcode 6 and higher offers a semi-automated system that builds and maintains a bridging header to expose Objective-C code to Swift. This takes the form of an additional header file that simply defines or imports all of the Objective-C symbols that are needed by the project's Swift code. At that point, Swift can refer to the types, functions, and variables declared in those imports as though they were written in Swift. Objective-C code can also use Swift code directly, by importing an automatically maintained header file with Objective-C declarations of the project's Swift symbols. For instance, an Objective-C file in a mixed project called "MyApp" could access Swift classes or functions with the code #import "MyApp-Swift.h"
. Not all symbols are available through this mechanism, however—use of Swift-specific features like generic types, non-object optional types, sophisticated enums, or even Unicode identifiers may render a symbol inaccessible from Objective-C.[90]
Swift also has limited support for attributes, metadata that is read by the development environment, and is not necessarily part of the compiled code. Like Objective-C, attributes use the @
syntax, but the currently available set is small. One example is the @IBOutlet
attribute, which marks a given value in the code as an outlet, available for use within Interface Builder (IB). An outlet is a device that binds the value of the on-screen display to an object in code.
On non-Apple systems, Swift does not depend on an Objective-C runtime or other Apple system libraries; a set of Swift "Corelib" implementations replace them. These include a "swift-corelibs-foundation" to stand in for the Foundation Kit, a "swift-corelibs-libdispatch" to stand in for the Grand Central Dispatch, and an "swift-corelibs-xctest" to stand in for the XCTest APIs from Xcode.[91]
As of 2019, with Xcode 11, Apple has also added a major new UI paradigm called SwiftUI. SwiftUI replaces the older Interface Builder paradigm with a new declarative development paradigm.[92]
Memory management
Swift uses Automatic Reference Counting (ARC) to manage memory. Apple used to require manual memory management in Objective-C, but introduced ARC in 2011 to allow for easier memory allocation and deallocation.[93] One problem with ARC is the possibility of creating a strong reference cycle, where objects reference each other in a way that you can reach the object you started from by following references (e.g. A references B, B references A). This causes them to become leaked into memory as they are never released. Swift provides the keywords weak
and unowned
to prevent strong reference cycles. Typically a parent-child relationship would use a strong reference while a child-parent would use either weak
reference, where parents and children can be unrelated, or unowned
where a child always has a parent, but parent may not have a child. Weak references must be optional variables, since they can change and become nil
.[94]
A closure within a class can also create a strong reference cycle by capturing self references. Self references to be treated as weak or unowned can be indicated using a capture list.
Debugging and other elements
A key element of the Swift system is its ability to be cleanly debugged and run within the development environment, using a read–eval–print loop (REPL), giving it interactive properties more in common with the scripting abilities of Python than traditional system programming languages. The REPL is further enhanced with playgrounds, interactive views running within the Xcode environment that respond to code or debugger changes on-the-fly.[95] Playgrounds allow programmers to add in Swift code along with markdown documentation. If some code changes over time or with regard to some other ranged input value, the view can be used with the Timeline Assistant to demonstrate the output in an animated way. In addition, Xcode has debugging features for Swift development including breakpoints, step through and step over statements, as well as UI element placement breakdowns for app developers.
Apple says that Swift is "an industrial-quality programming language that's as expressive and enjoyable as a scripting language".[96]
Comparisons to other languages
Swift is considered a C family programming language and is similar to C in various ways:
- Most operators in C also appear in Swift, although some operators such as
+
have slightly different behavior. For example,+
in Swift traps on overflow, whereas&+
is used to denote the C-like behavior of wrapping on overflow. - Curly braces are used to group statements.
- Variables are assigned using an equals sign, but compared using two consecutive equals signs. A new identity operator, ===, is provided to check if two data elements refer to the same object.
- Control statements
while
,if
, andswitch
are similar, but have extended functions, e.g., aswitch
that takes non-integer cases,while
andif
supporting pattern matching and conditionally unwrapping optionals,for
uses thefor i in 1...10
syntax. - Square brackets are used with arrays, both to declare them and to get a value at a given index in one of them.
It also has similarities to Objective-C:
- Basic numeric types (
Int, UInt, Float, Double
) - Class methods are inherited, like instance methods;
self
in class methods is the class the method was called on. - Similar
for
...in
enumeration syntax.
Differences from Objective-C include:
- Statements do not need to end with semicolons (
;
), though these must be used to allow more than one statement on a line. - No header files.
- Uses type inference.
- Generic programming.
- Functions are first-class objects.
- Enumeration cases can have associated data (algebraic data types).
- Operators can be redefined for classes (operator overloading), and new operators can be defined.
- Strings fully support Unicode. Most Unicode characters can be used in either identifiers or operators.
- No exception handling. Swift 2 introduces a different and incompatible error-handling model.[97]
- Several features of earlier C-family languages that are easy to misuse have been removed:
- Pointers are not exposed by default. There is no need for the programmer to keep track of and mark names for referencing or dereferencing.
- Assignments return no value. This prevents the common error of writing
i = 0
instead ofi == 0
by throwing a compile-time error. - No need to use
break
statements inswitch
blocks. Individual cases do not fall through to the next case unless thefallthrough
statement is used. - Variables and constants are always initialized and array bounds are always checked.
- Integer overflows, which result in undefined behavior for signed integers in C, are trapped as a run-time error in Swift. Programmers can choose to allow overflows by using the special arithmetical operators
&+
,&-
,&*
,&/
and&%
. The propertiesmin
andmax
are defined in Swift for all integer types and can be used to safely check for potential overflows, versus relying on constants defined for each type in external libraries. - The one-statement form of
if
andwhile
, which allows for the omission of braces around the statement, is unsupported. - C-style enumeration
for (int i = 0; i < c; i++)
, which is prone to off-by-one errors, is unsupported (from Swift 3 onward).[98] - The pre- and post- increment and decrement operators (
i++
,--i
...) are unsupported (from Swift 3 onward), more so since C-stylefor
statements are also unsupported from Swift 3 onward.[99]
Development and other implementations
Because Swift can run on Linux, it is sometimes also used as a server-side language.[100] Some web frameworks have already been developed, such as IBM's Kitura (now discontinued), Perfect and Vapor.
An official "Server APIs" work group has also been started by Apple,[101] with members of the Swift developer community playing a central role.[102]
A second free implementation of Swift that targets Cocoa, Microsoft's Common Language Infrastructure (.NET), and the Java and Android platform exists as part of the Elements Compiler from RemObjects Software.[103]
By combining toolchains from LLVM and Macintosh Programmer's Workshop, it is possible to run a very small subset of the language on Mac OS 9.[104]
See also
References
- U.S. patent no. 9329844
- "Swift Has Reached 1.0". Apple. September 9, 2014. Retrieved March 8, 2015.
- "Release 5.9.1". October 19, 2023. Retrieved October 20, 2023.
- "Swift, Objectively".
Swift is proprietary and closed: It is entirely controlled by Apple and there is no open source implementation.
- Lattner, Chris (June 11, 2014). "Re: [LLVMdev] [cfe-dev] [Advertisement] open positions in Apple's Swift compiler team". Archived from the original on July 14, 2014. Retrieved June 12, 2014.
You can imagine that many of us want it to be open source and part of LLVM, but the discussion hasn't happened yet, and won't for some time.
- Lattner, Chris (June 3, 2014). "Chris Lattner's Homepage". Chris Lattner. Retrieved June 3, 2014.
The Swift language is the product of tireless effort from a team of language experts, documentation gurus, compiler optimization ninjas, and an incredibly important internal dogfooding group who provided feedback to help refine and battle-test ideas. Of course, it also greatly benefited from the experiences hard-won by many other languages in the field, drawing ideas from Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, and far too many others to list.
- Lattner, Chris (June 3, 2014). "Chris Lattner's Homepage". Chris Lattner. Retrieved June 3, 2014.
I started work on the Swift Programming Language in July of 2010. I implemented much of the basic language structure, with only a few people knowing of its existence. A few other (amazing) people started contributing in earnest late in 2011, and it became a major focus for the Apple Developer Tools group in July 2013 [...] drawing ideas from Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, and far too many others to list.
- "Building assert() in Swift, Part 2: __FILE__ and __LINE__". Retrieved September 25, 2014.
- "Influences - The Rust Reference". doc.rust-lang.org. Retrieved May 2, 2020.
- Lardinois, Frederic (June 2, 2014). "Apple Launches Swift, A New Programming Language For Writing iOS And OS X Apps". TechCrunch. Retrieved September 7, 2022.
- Protocol-oriented Programming in Swift. Apple Inc. YouTube.
- "Concepts are similar to Rust Traits".
- Williams, Owen (June 2, 2014). "Tim Berners-Lee's sixtieth birthday Apple announces Swift, a new programming language for iOS". The Next Web. Retrieved June 2, 2014.
- "Apple's new programming language Swift is now open source". The Verge. December 3, 2015. Retrieved December 5, 2015.
- "Apple Open Sources Swift in Latest Pitch to the Enterprise". CIO Journal. The Wall Street Journal Blogs. December 3, 2015. Retrieved December 5, 2015.
- "Looking back on Swift 3 and ahead to Swift 4". Swift Forums. July 29, 2016. Retrieved November 19, 2018.
- "Swift-Evolution". Swift Evolution. Retrieved November 19, 2018.
- "The RedMonk Programming Language Rankings: January 2018 – tecosystems". redmonk.com. March 7, 2018. Retrieved November 20, 2018.
- Kremenek, Ted (March 25, 2019). "Swift 5 Released!".
- Kremenek, Ted (September 20, 2019). "Swift 5.1 Released!". Archived from the original on February 26, 2022. Retrieved October 28, 2019.
- Hudson, Paul (June 6, 2021). "What's new in Swift 5.5?". HackingWithSwift.com. Hacking with Swift. Retrieved June 8, 2021.
- "Swift 5.9 Released". Swift.org. September 18, 2023. Retrieved October 9, 2023.
- Platforms State of the Union, Session 102, Apple Worldwide Developers Conference, June 2, 2014
- The Swift Programming Language. Apple. June 2, 2014. Retrieved June 2, 2014.
- "Documentation". Swift.
- "Swift Has Reached 1.0". September 9, 2014. Retrieved September 10, 2014.
- "Xcode 6.1 Release Notes". October 22, 2014. Retrieved January 23, 2015.
- "Xcode 6.3 Release Notes". April 8, 2015. Retrieved April 8, 2015.
- "Swift 2 Apps in the App Store". Swift Blog. Retrieved March 13, 2016.
- "Swift 3.0 Released!". Swift.org. September 13, 2016. Archived from the original on October 14, 2016. Retrieved October 26, 2016.
- "Swift 4.0 Released!". Swift.org. September 17, 2017. Archived from the original on March 28, 2019. Retrieved March 1, 2018.
- "Swift 4.1 Released!". Swift.org. March 29, 2018. Archived from the original on April 25, 2019. Retrieved March 30, 2018.
- "Stack Overflow Developer Survey Results 2015".
- "Stack Overflow Developer Survey Results 2016".
- "Swift.org and Open Source". Swift.org. Apple Inc. Retrieved February 25, 2019.
- "Introducing the IBM Swift Sandbox — Swift". Swift. Retrieved December 5, 2015.
- Mayo, Benjamin (December 4, 2015). "Write Swift code in a web browser with the IBM Swift Sandbox". 9to5Mac. Retrieved December 5, 2015.
- "After Apple open sources it, IBM puts Swift programming in the cloud | ZDNet". ZDNet. Retrieved December 5, 2015.
- "Swift Package Catalog and Swift Sandbox Deprecation". Retrieved November 9, 2018.
- "Swift Playgrounds". Apple Developer. Retrieved June 19, 2016.
- "Swift Playgrounds — Preview". Apple. Retrieved June 19, 2016.
- Mayo, Benjamin (June 13, 2016). "Apple announces Swift Playgrounds for iPad at WWDC, public release in fall". 9to5Mac. Retrieved June 19, 2016.
- Cunningham, Andrew (January 10, 2017). "Longtime Apple programmer and Swift creator leaves Apple for Tesla". Ars Technica.
- Wuerthele, Mike (January 13, 2017). "New Swift project head Ted Kremenek said to be running the show behind the scenes for some time". AppleInsider.
- Daniel Eran Dilger. "WWDC19: SwiftUI was the brightest star in a galaxy of new ideas". AppleInsider. Retrieved July 19, 2019.
- "Swift.org - Download Swift". Retrieved June 21, 2020.
- "Android SDKs for Swift". GitHub. Retrieved September 10, 2021.
- "swift-lang package versions". Retrieved September 10, 2021.
- Readdle (January 15, 2020). "Swift for Android: Our Experience and Tools". Medium. Retrieved August 20, 2020.
- Anderson, Tim (March 30, 2020). "Official tailored Swift for Windows support promised in 5.3: Swift on more platforms – provided you do not need a GUI". The Register. Retrieved September 18, 2020.
- "The Swift Linux Port". Swift.org. Apple Inc. December 3, 2015. Retrieved August 3, 2016.
- Timmer, John (June 5, 2014). "A fast look at Swift, Apple's new programming language". Ars Technica. Condé Nast. Retrieved June 6, 2014.
- Kremenek, Ted (March 25, 2019). "Swift 5 Released!". Swift.org. Retrieved March 28, 2019.
- "Download Swift". Swift.org. Apple. Retrieved December 15, 2020.
- Kremenek, Ted (April 26, 2021). "Swift 5.4 Released!". Swift.org. Apple. Archived from the original on April 26, 2021. Retrieved April 26, 2021.
- Kremenek, Ted (March 14, 2022). "Swift 5.6 Released!". Swift.org. Apple. Retrieved March 14, 2022.
- "Release Swift 5.6.1 Release · apple/Swift". GitHub.
- "Release Swift 5.6.2 Release · apple/Swift". GitHub.
- "Release Swift 5.6.3 Release · apple/Swift". GitHub.
- Borla, Holly (September 12, 2022). "Swift 5.7 Released!". Swift.org. Apple. Retrieved September 23, 2022.
- "Release Swift 5.7.1 Release · apple/Swift". GitHub.
- "Release Swift 5.8 Release · apple/Swift". GitHub.
- "Release Swift 5.8.1 Release · apple/swift". GitHub. Retrieved June 14, 2023.
- "Release Swift 5.9 Release · apple/swift". GitHub. Retrieved September 18, 2023.
- Metz, Rachel (June 3, 2014). "Apple Seeks a Swift Way to Lure More Developers". Technology Review. Archived from the original on September 24, 2015. Retrieved February 11, 2018.
- Weber, Harrison (June 2, 2014). "Apple announces 'Swift,' a new programming language for macOS & iOS". VentureBeat.
- "Advantages Of Using Swift". themindstudios.com. February 24, 2017. Retrieved February 24, 2017.
- "Documentation". docs.swift.org. Retrieved October 15, 2023.
- "Documentation". docs.swift.org. Retrieved October 15, 2023.
- "Documentation". docs.swift.org. Retrieved October 15, 2023.
- "Closures — The Swift Programming Language (Swift 5.5)". docs.swift.org. Retrieved August 31, 2021.
- Macomber, Kyle; Yaskevich, Yavel; Gregor, Doug; McCall, John. "Multiple Trailing Closures". GitHub. Retrieved October 19, 2020.
- "Documentation". docs.swift.org. Retrieved October 16, 2023.
- "Strings and Characters". docs.swift.org. Retrieved October 16, 2023.
- "Access Control". developer.apple.com. Apple Inc. Retrieved October 25, 2016.
- "Nullable Types", C# Programming Guide, Microsoft.
- "Types". developer.apple.com. Apple Inc. Retrieved July 16, 2014.
- "Classes and Structures". Apple.com.
- Guhit, Fiel (February 14, 2015). "Performance Case Study on Swift 1.1, Swift 1.2, and Objective-C".
- Building Better Apps with Value Types. Apple.
- "NSCopying Protocol Reference". Apple.
- "Working with Protocols". Apple.
- Thompson, Mattt (September 2, 2014). "Swift Default Protocol Implementations". NSHipster.
- "Swift standard library statistics". swiftinit.org. Swiftinit. Retrieved October 2, 2023.
- "swift-evolution/proposals/0304-structured-concurrency.md at main · apple/swift-evolution". GitHub. Retrieved October 16, 2023.
- "swift-evolution/proposals/0296-async-await.md at main · apple/swift-evolution". GitHub. Retrieved October 16, 2023.
- "Do Swift-based apps work on macOS 10.9/iOS 7 and lower?", StackOverflow
- Inc, Apple (September 18, 2023). "Swift 5.9 Released". Swift.org. Retrieved October 9, 2023.
{{cite web}}
:|last=
has generic name (help) - "Writing Swift Classes with Objective-C Behavior", Apple Inc.
- "Migrating Your Objective-C Code to Swift".
- "Swift and Objective-C in the Same Project", Apple Inc.
- "Apple: search "corelib"". GitHub.
- "Xcode - SwiftUI- Apple Developer". developer.apple.com. Retrieved February 1, 2021.
- "Automatic Reference Counting", Apple Inc.
- Lanier, Brian; Groff, Joe. "Intermediate Swift". Apple. Retrieved July 3, 2014.
- Metz, Cade. "Why Coders Are Going Nuts Over Apple's New Programming Language". Wired. Retrieved July 16, 2014.
- About Swift, Apple Inc.
- "Error-Handling in Swift-Language". stackoverflow.com.
- "apple/swift-evolution". GitHub. Retrieved April 4, 2016.
- "apple/swift-evolution". GitHub. Retrieved April 4, 2016.
- Barbosa, Greg (February 22, 2016). "IBM brings Swift to the cloud, releases web framework Kitura written in Apple's programming language". 9to5Mac. Retrieved May 16, 2016.
- "Server APIs Work Group". Swift.org. October 25, 2016. Retrieved October 28, 2016.
- "Swift.org". Swift.org. Archived from the original on May 10, 2021. Retrieved October 28, 2016.
- "RemObjects Elements Compiler". Retrieved January 17, 2016.
- Rose, Jordan (April 1, 2020). "Swift on Mac OS 9". -dealloc.