加号两边的数类型须相同
1 | let three = 3 |
类型别名
typealias AudioSample = UInt16
元组(tuples)
把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。
1 | let http404Error = (404, "Not Found") |
将一个元组的内容分解(decompose)成单独的常量和变量
1 | let (statusCode, statusMessage) = http404Error |
如果你只需要一部分元组值,分解的时候可以把要忽略的部分用下划线(_)标记:
1 | let (justTheStatusCode, _) = http404Error |
此外,你还可以通过下标来访问元组中的单个元素,下标从零开始:
1 | print("The status code is \(http404Error.0)") |
你可以在定义元组的时候给单个元素命名:
1 | let http200Status = (statusCode: 200, description: "OK") |
给元组中的元素命名后,你可以通过名字来获取这些元素的值:
1 | print("The status code is \(http200Status.statusCode)") |
可选类型(optionals)
nil 表示“缺少一个合法的对象”
声明一个可选常量或者变量但是没有赋值,它们会自动被设置为 nil:
1 | var surveyAnswer: String? |
当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号(!)来获取值。这个惊叹号表示“我知道这个可选有值,请使用它。”这被称为可选值的强制解析(forced unwrapping):
1 | if convertedNumber != nil { |
可选绑定
使用可选绑定(optional binding)来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变量。可选绑定可以用在 if 和 while 语句中,这条语句不仅可以用来判断可选类型中是否有值,同时可以将可选类型中的值赋给一个常量或者变量。if 和 while 语句,请参考 控制流。
像下面这样在 if 语句中写一个可选绑定:
1 | if let constantName = someOptional { |
你可以像上面这样使用可选绑定来重写 在 可选类型 举出的 possibleNumber 例子:
1 | if let actualNumber = Int(possibleNumber) { |
这段代码可以被理解为:
“如果 Int(possibleNumber) 返回的可选 Int 包含一个值,创建一个叫做 actualNumber 的新常量并将可选包含的值赋给它。”
如果转换成功,actualNumber 常量可以在 if 语句的第一个分支中使用。它已经被可选类型 包含的 值初始化过,所以不需要再使用 ! 后缀来获取它的值。在这个例子中,actualNumber 只被用来输出转换结果。
你可以在可选绑定中使用常量和变量。如果你想在 if 语句的第一个分支中操作 actualNumber 的值,你可以改成 if var actualNumber,这样可选类型包含的值就会被赋给一个变量而非常量。
你可以包含多个可选绑定或多个布尔条件在一个 if 语句中,只要使用逗号分开就行。只要有任意一个可选绑定的值为 nil,或者任意一个布尔条件为 false,则整个 if 条件判断为 false,这时你就需要使用嵌套 if 条件语句来处理,如下所示:
1 | if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 { |
赋值
如果赋值的右边是一个多元组,它的元素可以马上被分解成多个常量或变量:
1 | let (x, y) = (1, 2) |
与 C 语言和 Objective-C 不同,Swift 的赋值操作并不返回任何值。所以下面语句是无效的:
1 | if x = y { |
通过将 if x = y 标记为无效语句,Swift 能帮你避免把 (==)错写成(=)这类错误的出现。
空合运算符(Nil Coalescing Operator)
空合运算符(a ?? b)将对可选类型 a 进行空判断,如果 a 包含一个值就进行解包,否则就返回一个默认值 b。表达式 a 必须是 Optional 类型。默认值 b 的类型必须要和 a 存储值的类型保持一致。
空合运算符是对以下代码的简短表达方法:
a != nil ? a! : b
上述代码使用了三元运算符。当可选类型 a 的值不为空时,进行强制解封(a!),访问 a 中的值;反之返回默认值 b。无疑空合运算符(??)提供了一种更为优雅的方式去封装条件判断和解封两种行为,显得简洁以及更具可读性。
注意
如果 a 为非空值(non-nil),那么值 b 将不会被计算。这也就是所谓的短路求值。
下文例子采用空合运算符,实现了在默认颜色名和可选自定义颜色名之间抉择:
1 | let defaultColorName = "red" |
userDefinedColorName 变量被定义为一个可选的 String 类型,默认值为 nil。由于 userDefinedColorName 是一个可选类型,我们可以使用空合运算符去判断其值。在上一个例子中,通过空合运算符为一个名为 colorNameToUse 的变量赋予一个字符串类型初始值。 由于 userDefinedColorName 值为空,因此表达式 userDefinedColorName ?? defaultColorName 返回 defaultColorName 的值,即 red。
如果你分配一个非空值(non-nil)给 userDefinedColorName,再次执行空合运算,运算结果为封包在 userDefaultColorName 中的值,而非默认值。
1 | userDefinedColorName = "green" |
区间运算符(Range Operators)
闭区间运算符
闭区间运算符(a…b)定义一个包含从 a 到 b(包括 a 和 b)的所有值的区间。a 的值不能超过 b。
1 | for index in 1...5 { |
半开区间运算符
半开区间运算符(a..<b)定义一个从 a 到 b 但不包括 b 的区间。
半开区间的实用性在于当你使用一个从 0 开始的列表(如数组)时,非常方便地从0数到列表的长度。
1 | let names = ["Anna", "Alex", "Brian", "Jack"] |