1. What is Swift?
Swift is a programming language released by Apple in WWDC 2014. Here we quote the original words of The Swift Programming Language:
Swift is a new programming language for iOS and OS X apps that builds on the best of C and Objective-C, without the constraints of C compatibility.
Swift adopts safe programming patterns and adds modern features to make programming easier, more flexible and more fun.
Swift's clean slate, backed by the mature and much-loved Cocoa and Cocoa Touch frameworks, is an opportunity to imagine how software development works.
Swift is the first industrial-quality systems programming language that is as expressive and enjoyable as a scripting language.
Simply put:
Swift is used to write iOS and OS X programs. (It is estimated that it will not support other Premium)
Swift draws on the advantages of C and Objective-C and is more powerful and easy to use.
Swift can use existing Cocoa and Cocoa Touch frameworks.
Swift combines high performance of compiled languages and interactiveness of scripting languages.
2. Swift language overview
1. Basic concepts
Note: The code in this section is derived from A Swift Tour in The Swift Programming Language.
1., world
Similar to a scripting language, the following code is a complete Swift program.
println("Hello, world")
1.2. Variables and constants
Swift uses var to declare variables and let declare constants.
ar myVariable = 42
myVariable = 50
let myConstant = 42
1.3. Type Deduction
Swift supports Type Inference, so the above code does not need to specify a type, if you need to specify a type:
Swift does not support implicit type conversion (Implicitly casting), so the following code requires explicit type conversion (Explocitly casting):
let label = "The width is "
let width = 94
let width = label + String(width)
1.4. String formatting
Swift uses (item) form to format strings:
let apples = 3
let oranges = 5
let appleSummary = "I have (apples) apples."
let appleSummary = "I have (apples + oranges) pieces of fruit."
1.5. Arrays and Dictionary
Swift uses the [] operator to declare arrays and dictionary:
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
Generally, initializer syntax is used to create empty arrays and empty dictionaries:
let emptyArray = String[]()
let emptyDictionary = Dictionary<String, Float>()
If the type information is known, you can declare an empty array using [] and an empty dictionary using [:].
2. Control flow
2.1 Overview
Swift's conditional statements include if and switch, and loop statements include for-in, for, while and do-while. Loop/judgment conditions do not require brackets, but loop/judgment body requires brackets:
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
if score > 50 {
teamScore += 3
} else {
teamScore += 1
}
}
2.2 Nullable type
Combining if and let, nullable variables can be easily processed. For null values, do you need to add after the type declaration? Explicitly indicate that the type can be nullable.
var optionalString: String? = "Hello"
optionalString == nil
var optionalName: String? = "John Appleseed"
var gretting = "Hello!"
if let name = optionalName {
gretting = "Hello, (name)"
}
2.3 Flexible switch
Swift supports a variety of comparison operations:
let vegetable = "red pepper"
switch vegetable {
case "celery":
let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
let vegetableComment = "That would make a good tea sandwich."
case let x where ("pepper"):
let vegetableComment = "Is it a spicy (x)?"
default:
let vegetableComment = "Everything tastes good in soup."
}
2.4 Other cycles
For-in can also be used to traverse dictionaries in addition to traversing arrays:
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
}
}
largest
While loop and do-while loop:
var n = 2
while n < 100 {
n = n * 2
}
var m = 2
do {
m = m * 2
} while m < 100
m
Swift supports traditional for loops, and in addition, the same logic can be achieved by combining... (generating an interval) and for-in.
var firstForLoop = 0
for i in 0..3 {
firstForLoop += i
}
firstForLoop
var secondForLoop = 0
for var i = 0; i < 3; ++i {
secondForLoop += 1
}
secondForLoop
Note: In addition to... Swift also generates a range that is closed before and open afterwards, while... generates a range that is closed before and closed afterwards.
3. Functions and closures
3.1 Function
Swift declares functions using func keywords:
func greet(name: String, day: String) -> String {
return "Hello (name), today is (day)."
}
greet("Bob", "Tuesday")
Return multiple values via tuple:
func getGasPrices() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
}
getGasPrices()
Supports functions with variable length parameters:
func sumOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
sumOf()
sumOf(42, 597, 12)
Functions can also be nested:
func returnFifteen() -> Int {
var y = 10
func add() {
y += 5
}
add()
return y
}
returnFifteen()
As a first-class object, the function can be either as a return value or as a parameter:
func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
func lessThanTen(number: Int) -> Bool {
return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, lessThanTen)
3.2 Closure
In essence, functions are special closures, and {} can be used to declare anonymous closures in Swift:
({
(number: Int) -> Int in
let result = 3 * number
return result
})
When the type of the closure is known, the following simplified writing can be used:
({ number in 3 * number })
In addition, parameters can be used by the position of the parameter. When the last parameter of the function is a closure, the following syntax can be used:
4. Classes and Objects
4.1 Creating and using classes
Swift uses class to create a class that can contain fields and methods:
class Shape {
var numberOfSides = 0
func simpleDescription() -> String {
return "A shape with (numberOfSides) sides."
}
}
Create an instance of the Shape class and call its fields and methods.
var shape = Shape()
= 7
var shapeDescription = ()
Build an object through init, you can use self to explicitly refer to member fields (name) or implicitly refer to (numberOfSides).
class NamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String) {
= name
}
func simpleDescription() -> String {
return "A shape with (numberOfSides) sides."
}
}
Use deinit for cleaning.
4.2 Inheritance and polymorphism
Swift supports inheritance and polymorphism (override parent class method):
class Square: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
= sideLength
(name: name)
numberOfSides = 4
}
func area() -> Double {
return sideLength * sideLength
}
override func simpleDescription() -> String {
return "A square with sides of length (sideLength)."
}
}
let test = Square(sideLength: 5.2, name: "my test square")
()
()
Note: If the simpleDescription method here is not identified as override, a compilation error will be raised.
4.3 Attributes
To simplify the code, Swift introduced properties, see the following perimeter field:
class EquilateralTriangle: NamedShape {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
= sideLength
(name: name)
numberOfSides = 3
}
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
override func simpleDescription() -> String {
return "An equilateral triagle with sides of length (sideLength)."
}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
= 9.9
Note: In the evaluator (setter), the received value is automatically named newValue.
4.4 willSet and didSet
The constructor of EquilateralTriangle performs the following operations:
1. Assign values to attributes of subtypes.
2. Call the constructor of parent type.
3. Modify the properties of the parent type.
If you do not need to calculate the value of the attribute, but need to perform some operations before and after assignment, use willSet and didSet:
class TriangleAndSquare {
var triangle: EquilateralTriangle {
willSet {
=
}
}
var square: Square {
willSet {
=
}
}
init(size: Double, name: String) {
square = Square(sideLength: size, name: name)
triangle = EquilateralTriangle(sideLength: size, name: name)
}
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
= Square(sideLength: 50, name: "larger square")
This ensures that triangle and square have equal sideLength.
4.6 Calling methods
In Swift, the parameter names of a function can only be used inside the function, but the parameter names of the method can also be used externally in addition to being used internally (except the first parameter), for example:
class Counter {
var count: Int = 0
func incrementBy(amount: Int, numberOfTimes times: Int) {
count += amount * times
}
}
var counter = Counter()
(2, numberOfTimes: 7)
Note that Swift supports aliasing method parameters: in the above code, numberOfTimes is external and times is internal.
Another use of 4.7?
When using nullable values, ? can appear before a method, property, or subscript. If the value before ? is nil, then the expression after ? will be ignored, and the original expression will directly return nil, for example:
let sideLength = optionalSquare?.sideLength
When optionalSquare is nil, the sideLength attribute call is ignored.
5. Enumeration and Structure
5.1 enumeration
Use enum to create enums - note that Swift enums can be associated with methods:
enum Rank: Int {
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King
func simpleDescription() -> String {
switch self {
case .Ace:
return "ace"
case .Jack:
return "jack"
case .Queen:
return "queen"
case .King:
return "king"
}
}
}
let ace =
let aceRawValue = ()
Use toRaw and fromRaw to convert between raw (raw) numeric and enumeration values:
if let convertedRank = (3) {
let threeDescription = ()
}
Note that the member value in the enum is the actual value and has no necessary association with the original value.
In some cases, there is no meaningful original value in the enumeration, and the original value can be directly ignored:
enum Suit {
case Spades, Hearts, Diamonds, Clubs
func simpleDescription() -> String {
switch self {
case .Spades:
return "spades"
case .Hearts:
return "hearts"
case .Diamonds:
return "diamonds"
case .Clubs:
return "clubs"
}
}
}
let hearts =
let heartsDescription = ()
In addition to associating methods, enums also support associating values on their members. Different members of the same enum can have different associated values:
enum ServerResponse {
case Result(String, String)
case Error(String)
}
let success = ("6:00 am", "8:09 pm")
let failure = ("Out of cheese.")
switch success {
case let .Result(sunrise, sunset):
let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
case let .Error(error):
let serverResponse = "Failure... \(error)"
}
5.2 Structure
Swift uses the struct keyword to create structures. Structures support the characteristics of these classes such as constructors and methods. The biggest difference between a structure and a class is that the instance of a structure is passed by value, while the instance of a class is passed by reference.
struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The \(()) of \(())"
}
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = ()
5.3 Protocol and extension protocol
Swift uses protocol to define the protocol:
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}
Types, enums and structures can all implement (adopt) protocols:
class SimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class."
var anotherProperty: Int = 69105
func adjust() {
simpleDescription += " Now 100% adjusted."
}
}
var a = SimpleClass()
()
let aDescription =
struct SimpleStructure: ExampleProtocol {
var simpleDescription: String = "A simple structure"
mutating func adjust() {
simpleDescription += " (adjusted)"
}
}
var b = SimpleStructure()
()
let bDescription =
5.4 Extensions
Extension is used to add new features (such as new methods or properties) to existing types. Swift uses extension to declare extensions:
extension Int: ExampleProtocol {
var simpleDescription: String {
return "The number \(self)"
}
mutating func adjust() {
self += 42
}
}
5.5 Generics
Swift uses <> to declare generic functions or generic types:
func repeat<ItemType>(item: ItemType, times: Int) -> ItemType[] {
var result = ItemType[]()
for i in 0..times {
result += item
}
return result
}
repeat("knock", 4)
Swift also supports the use of generics in classes, enums, and structures:
// Reimplement the Swift standard library's optional type
enum OptionalValue<T> {
case None
case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)
Sometimes some requirements are required for generics, such as requiring a certain generic type to implement a certain interface or inherit from a certain type, and two generic types belong to the same type, etc. Swift describes these requirements through where:
func anyCommonElements <T, U where T: Sequence,
U: Sequence, : Equatable,
== > (lhs: T, rhs: U) -> Bool {
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
return true
}
}
}
return false
}
anyCommonElements([1, 2, 3], [3])
This is the end of the Swift language overview. Interested friends, please read the Swift Programming Language.
Next, let’s talk about my personal feelings about Swift.
Personal feelings
Note: The following feelings are purely personal opinions and are for reference only.
A hodgepodge
Although I had been in contact with Swift for less than two hours, it was easy to see that Swift absorbed a large number of elements from other programming languages, including but not limited to:
Property, Nullable type syntax, and Generic Type syntax originate from C#. The format style is similar to Go (there is no semicolon at the end of the sentence, and there is no need for brackets to judge the conditions). Python-style current instance reference syntax (using self) and list dictionary declaration syntax. Haskell style interval declaration syntax (such as 1..3, 1...3). The protocol and extension are derived from Objective-C (use at will for your own products). Enum types are much like Java (can have members or methods). The concepts of class and struct are very similar to C#.
Note that this is not to say that Swift is plagiarism - in fact, there are basically all the tricks that can be played with in programming languages, and Swift chooses all the features that I think are quite good.
And, there is one advantage of this hodgepodge—that is, no other programming language developer will find Swift unfamiliar—that is very important.
Refuse implicity
Swift removes some implicit operations, such as implicit type conversion and implicit method overloading, and it does a pretty good job.
Swift's application direction
I think Swift mainly has the following two application directions:
1. Education
I mean programming education. The biggest problem with existing programming languages is that their interactivity is extremely poor, which leads to a steep learning curve. I believe that Swift and its highly interactive programming environment can break this situation and allow more people, especially teenagers, to learn to program.
It is necessary to mention Brec Victor's Inventing on Principle again. After watching this video, you will understand what a highly interactive programming environment can bring.
2. Application development
The existing iOS and OS X application development uses Objective-C, which is a language that is verbose and has a relatively steep learning curve. If Swift can provide a simple interoperable interface with the existing Obj-C framework, I believe that a large number of programmers will switch to Swift; at the same time, Swift's simple syntax will also bring a considerable number of developers of other platforms.
In short, the last time a large company launched a programming language and its programming platform was in 2000 (Microsoft launched C#). Almost 15 years later, Apple launched Swift. As a developer, I am very happy to witness the birth of a programming language.