快乐的鲸鱼

swift学习笔记【1】

2016/12/18

基础部分

笔记。多摘抄于The Swift Programming Language 中文版

声明常量和变量

1
2
let maxNumberOfUsers = 10
var currentUser = "Jim"

类型标注

1
2
3
var welcomeMessage: String
welcomeMessage = "Hello"
var red, green, blue: Double

输出常量和变量

1
2
let name = "Jim"
print("Hello, \(name)")

类型转换

需要显式转换数据类型

1
2
let num1: Uint8 = 1
let num2: Double = Double(num1)

元组

元组可作为方法的返回值,一次返回多个数据。或者普通的传参使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 元组的创建
let http404Error = (404, "Not Found")
// http404Error 的类型是 (Int, String),值是 (404, "Not Found")

// 元组的内容分解
let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
// 只需要一部分元组值,分解的时候可以把要忽略的部分用下划线(_)标记
let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
// 可以通过下标来访问元组中的单个元素
print("The status code is \(http404Error.0)")
// 可以在定义元组的时候给单个元素命名
let http200Status = (statusCode: 200, description: "OK")
print("The status code is \(http200Status.statusCode)")

可选类型(optionals)

使用可选类型来处理值可能缺失的情况。

1
2
3
4
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber 被推测为类型 "Int?", 或者类型 "optional Int"
// 因为如果Int()类型转换函数传入的字符串为非法字符串,则会返回nil

nil

1
2
3
4
5
6
7
8
9
// 可以给可选变量赋值为nil来表示它没有值
var serverResponseCode: Int? = 404
// serverResponseCode 包含一个可选的 Int 值 404
serverResponseCode = nil
// serverResponseCode 现在不包含值

// 如果声明一个可选常量或者变量但是没有赋值,它们会自动被设置为 nil
var surveyAnswer: String?
// surveyAnswer 被自动设置为 nil

if 语句以及强制解析

用来判断一个可选值是否包含值

当确定可选类型确实包含值之后,就可以在可选的名字后面加一个感叹号(!)来获取值。这叫做可选值的强制解析**(forced unwrapping)

1
2
3
4
if convertedNumber != nil {
print("convertedNumber has an integer value of \(convertedNumber!).")
}
// 输出 "convertedNumber has an integer value of 123."

可选绑定(optional binding)

可选绑定可以用在 if 和 while 语句中,这条语句不仅可以用来判断可选类型中是否有值,同时可以将可选类型中的值赋给一个常量或者变量。

1
2
3
4
5
6
if let actualNumber = Int(possibleNumber) {
print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
} else {
print("\'\(possibleNumber)\' could not be converted to an integer")
}
// 输出 "'123' has an integer value of 123"

隐式解析可选类型

有时候在程序架构中,第一次被赋值之后,可以确定一个可选类型_总会_有值。在这种情况下,每次都要判断和解析可选值是非常低效的,因为可以确定它总会有值。

这种类型的可选状态被定义为隐式解析可选类型(implicitly unwrapped optionals)。把想要用作可选的类型的后面的问号(String?)改成感叹号(String!)来声明一个隐式解析可选类型。

隐式解析可选类型主要被用在 Swift 中类的构造过程中。

1
2
3
4
5
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // 需要感叹号来获取值

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // 不需要感叹号

空合运算符(Nil Coalescing Operator)

空合运算符(a ?? b)将对可选类型 a 进行空判断,如果 a 包含一个值就进行解封,否则就返回一个默认值 b。表达式 a 必须是 Optional 类型。默认值 b 的类型必须要和 a 存储值的类型保持一致。

1
2
3
4
5
let defaultColorName = "red"
var userDefinedColorName: String? //默认值为 nil

var colorNameToUse = userDefinedColorName ?? defaultColorName
// userDefinedColorName 的值为空,所以 colorNameToUse 的值为 "red"

区间运算符(Range Operators)

1
2
3
4
5
6
7
8
9
10
11
// 闭区间运算符
for index in 1...5 {
print("\(index) * 5 = \(index * 5)")
}

// 半开区间运算符
let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
print("第 \(i + 1) 个人叫 \(names[i])")
}

集合类型 (Collection Types)

数组(Arrays)

一个数组只能存放同一类型的数据

创建一个空数组

1
2
3
4
5
var someInts = [Int]()
someInts.append(3)
// someInts 现在包含一个 Int 值
someInts = []
// someInts 现在是空数组,但是仍然是 [Int] 类型的

创建一个带有默认值的数组

1
2
var threeDoubles = Array(repeating: 0.0, count: 3)
// threeDoubles 是一种 [Double] 数组,等价于 [0.0, 0.0, 0.0]

用数组字面量构造数组

1
2
3
var shoppingList: [String] = ["Eggs", "Milk"]
// shoppingList 已经被构造并且拥有两个初始项。
// 这个例子中可以省略数据类型,swift可以推断出数据类型

控制流(Control Flow)

Switch

区间匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let approximateCount = 62
let countedThings = "moons orbiting Saturn"
var naturalCount: String
switch approximateCount {
case 0:
naturalCount = "no"
case 1..<5:
naturalCount = "a few"
case 5..<12:
naturalCount = "several"
case 12..<100:
naturalCount = "dozens of"
case 100..<1000:
naturalCount = "hundreds of"
default:
naturalCount = "many"
}
print("There are \(naturalCount) \(countedThings).")
// 输出 "There are dozens of moons orbiting Saturn."

我们可以使用元组在同一个switch语句中测试多个值。元组中的元素可以是值,也可以是区间。另外,使用下划线(_)来匹配所有可能的值。

下面的例子展示了如何使用一个(Int, Int)类型的元组来分类下图中的点(x, y):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
print("(0, 0) is at the origin")
case (_, 0):
print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
print("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
// 输出 "(1, 1) is inside the box"

值绑定(Value Bindings)

case 分支允许将匹配的值绑定到一个临时的常量或变量,并且在case分支体内使用 —— 这种行为被称为值绑定(value binding),因为匹配的值在case分支体内,与临时的常量或变量绑定。

下面的例子展示了如何在一个(Int, Int)类型的元组中使用值绑定来分类下图中的点(x, y):

1
2
3
4
5
6
7
8
9
10
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
print("on the x-axis with an x value of \(x)")
case (0, let y):
print("on the y-axis with a y value of \(y)")
case let (x, y):
print("somewhere else at (\(x), \(y))")
}
// 输出 "on the x-axis with an x value of 2"

Where

case 分支的模式可以使用where语句来判断额外的条件。

下面的例子把下图中的点(x, y)进行了分类:

1
2
3
4
5
6
7
8
9
10
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
print("(\(x), \(y)) is just some arbitrary point")
}
// 输出 "(1, -1) is on the line x == -y"

复合匹配

当多个条件可以使用同一种方法来处理时,可以将这几种可能放在同一个case后面,并且用逗号隔开。当case后面的任意一种模式匹配的时候,这条分支就会被匹配。并且,如果匹配列表过长,还可以分行书写:

1
2
3
4
5
6
7
8
9
10
11
let someCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
print("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
print("\(someCharacter) is a consonant")
default:
print("\(someCharacter) is not a vowel or a consonant")
}
// 输出 "e is a vowel"
CATALOG
  1. 1. 基础部分
    1. 1.0.1. 声明常量和变量
    2. 1.0.2. 类型标注
    3. 1.0.3. 输出常量和变量
    4. 1.0.4. 类型转换
    5. 1.0.5. 元组
    6. 1.0.6. 可选类型(optionals)
    7. 1.0.7. nil
    8. 1.0.8. if 语句以及强制解析
    9. 1.0.9. 可选绑定(optional binding)
    10. 1.0.10. 隐式解析可选类型
    11. 1.0.11. 空合运算符(Nil Coalescing Operator)
    12. 1.0.12. 区间运算符(Range Operators)
  • 2. 集合类型 (Collection Types)
    1. 2.1. 数组(Arrays)
      1. 2.1.1. 创建一个空数组
      2. 2.1.2. 创建一个带有默认值的数组
      3. 2.1.3. 用数组字面量构造数组
  • 3. 控制流(Control Flow)
    1. 3.1. Switch
      1. 3.1.1. 区间匹配
      2. 3.1.2. 值绑定(Value Bindings)
      3. 3.1.3. Where
      4. 3.1.4. 复合匹配