The Swift Programming Language 4.0 中文版学习笔记 1
1. 基础部分
注释
嵌套注释:
/* A
/* B */
/
常量和变量
常量和变量名可以使用Unicode字符来命名,但不能包含数学符号,箭头,保留的(或者非法的)Unicode码位,连线与制表符。也不能以数字开头。
常量和变量一旦声明为确定的类型,即不能改变其存储的值的类型。同时,常量和变量不能互转。
数字
除非需要特定长度的整数,一般来说使用Int
就够了,这样可以提供代码一致性和可复用性。
尽量不要使用UInt
,除非需要存储一个和当前平台原生字长相同的无符号整数。否则,最好使用Int
,即使要存储的值已知是非负的。统一使用Int
可以提高代码的可复用性,避免不同类型数字之间的转换,并且匹配数字的类型推断。
Double
类型的精确度高于Float
,选择哪个类型取决于代码需要处理的值的范围,在两种类型都匹配的情况下,优先选择Double
。
类型推断
数字类字面量可由编译器推断类型,而数字类常量和变量必须显式转换为其他类型。
类型别名
类型别名typealias
就是给现有类型定义另一个名字。
元组
可以把任何顺序的类型组合成一个元组,这个元组可以包含所有类型。
可以将一个元组的内容分解为单独的常量和变量。如果只需要一部分元组值,分解的时候可以把要忽略的部分用下划线(_
)标记。
定义元组的时候,可以给单个元素命名。
let http200Status = (statusCode: 200,description: “OK")
print(“status code: \(http200Status.statusCode),description: \(http200Status.1)”)
let (justTheStatusCode,_) = http200Status
可选类型
可选类型可以暗示任意类型的值缺失,并不需要一个如Objective-C中的NSNotFound
这样的特殊值来标记非对象类型。
可以给可选变量赋值为nil
来表示它没有值,nil
不能用于非可选的常量和变量。
Swift的nil
和Objective-C的nil
并不一样。后者是一个指向不存在对象的指针。在Swift中,nil
不是指针——它是一个确定的值,用来表示值缺失。
可选绑定
使用可选绑定(optional binding)来判断可选类型是否包含值,如果包含值就把值赋值给一个临时常量/变量。可选绑定可以用在if
和while
语句中。
注意:在if
条件语句中使用常量/变量来创建一个可选绑定,仅在if
语句的句中(body
)中才能获取到值。相反,在guard
语句中使用常量/变量来创建一个可选绑定,仅在guard
语句外且在语句后才能获取到值。
隐式解析可选类型
有时在程序架构中,第一次赋值之后可以确定一个可选类型总会有值。这种情况下,每次都要判断和解析可选类型是非常低效的。这种类型的可选状态被定义为隐式解析可选类型(implicitly unwrapped optionals)。把想要用做可选类型的后面的问号(String?
)改为感叹号(String!
)来声明一个隐式解析可选类型。
注意:只在确定一个变量不可能变为nil
时才使用隐式解析可选类型。否则在隐式解析可选类型没有值的时候尝试取值,会触发运行时错误;正如和没有值的普通可选类型后面加一个惊叹号一样。
2. 基本运算
空合运算符(Nil Coalescing Operator)
空合运算符(a ?? b
)将对可选类型a
进行空判断,如果包含一个值就进行解封,否则就返回一个默认值b
。注意这里,a
必须是可选类型, 默认值b
的类型必须与a
存储值的类型保持一致。
区间运算符(Range Operators)
a…b // 闭区间运算符
a..<b // 半开区间运算符
array[2…] // 单侧区间1
array[…2] // 单侧区间2
3. 字符串和字符
多行字符串字面量
由一对三个双引号"""
包裹着文本,可实现跨越多行的字符串。注意:从开启引号当前行之后的第一行开始,到关闭引号当前行之前的一行为止。可以在行尾写一个反斜杠(\
)作为续行符来实现增强代码可读性且避免换行。
关闭引号当前行之前的空白字符串告诉Swift编译器其他各行多少空白字符串需要忽略。
字符串是值类型
Swift的String
是值类型。拷贝的方式保证了在函数/方法中传递的是字符串的值。
连接字符串和字符
字符串支持的运算符包括+
+=
==
!=
,也可以使用append()
方法将一个字符附加到一个字符串变量的尾部。
字符串插值
字符串插值是构建新字符串的方式之一,可以包含常量、变量、字面量和表达式。
4. 集合类型(Collection Types)
Swift语言提供Array
(有序数据集合)、Set
(无序不重复数据集合)、 Dictionary
(无序键值对集合)三种基本集合类型用来存储集合数据。它们存储的数据类型必须明确。
集合的可变性
如果集合赋值给一个变量,则这个集合是可变的;否则分配给一个常量,则是不可变的。
数组(Array)
数组Array
支持使用加法运算符+
和加法赋值运算符+=
。[]
是空数组。
注意:自定义类型通过实现
Hashable
协议,可以作为集合的值的类型或者是字典的键的类型。实现Hashable
协议,需要提供一个类型为Int
的可读属性hashValue
。
集合(Set)
你可以高效地完成Set
的一些基本操作,比如把两个集合组合到一起,判断两个集合共有元素,或者判断两个集合是否全包含,部分包含或者不相交。
字典(Dictionary)
通过访问keys
或者values
属性,我们也可以遍历字典的键或者值。
5. 控制流
Swift提供了多种流程控制结构,包括可以多次执行任务的while/(repeat-while)循环,基于特定条件选择执行不同代码分支的if、guard和switch语句,还有控制流程跳转到其他代码位置的break和continue语句。
Swift 还提供了for-in循环,用来更简单地遍历数组(Array),字典(Dictionary),区间(Range),字符串(String)和其他序列类型。
Swift 的switch语句比 C 语言中更加强大。case 还可以匹配很多不同的模式,包括范围匹配,元组(tuple)和特定类型匹配。switch语句的 case 中匹配的值可以声明为临时常量或变量,在 case 作用域内使用,也可以配合where来描述更复杂的匹配条件。
Switch
区间匹配
case 分支的模式也可以是一个值的区间。
元组
我们可以使用元组在同一个switch语句中测试多个值。元组中的元素可以是值,也可以是区间。另外,使用下划线(_)来匹配所有可能的值。
值绑定(Value Bindings)
case 分支允许将匹配的值声明为临时常量或变量,并且在case分支体内使用 —— 这种行为被称为值绑定(value binding)。
case 分支的模式可以使用where语句来判断额外的条件。
复合匹配
当多个条件可以使用同一种方法来处理时,可以将这几种可能放在同一个case后面,并且用逗号隔开。
控制转移语句
Swift有五种控制转移语句:
- continue
- break
- fallthrough
- return
- throw
在 Swift 里,switch语句不会从上一个 case 分支跳转到下一个 case 分支中。
相比之下,C 语言要求你显式地插入break语句到每个 case 分支的末尾来阻止自动落入到下一个 case 分支中。
如果你确实需要 C 风格的贯穿的特性,你可以在每个需要该特性的 case 分支中使用fallthrough关键字。
可以使用标签(statement label)来标记一个循环体或者条件语句,对于一个条件语句,你可以使用break加标签的方式,来结束这个被标记的语句。对于一个循环语句,你可以使用break或者continue加标签,来结束或者继续这条被标记语句的执行。
例如,针对循环体的标签:
label name: while condition { statements }
提前退出
像if
语句一样,guard
的执行取决于一个表达式的布尔值。我们可以使用guard
语句来要求条件必须为真时,以执行guard
语句后的代码。不同于if
语句,一个guard
语句总是有一个else
从句,如果条件不为真则执行else
从句中的代码。
guard let/var condition else {
return // break/continue/throw/fatalError()
}
相比于可以实现同样功能的if语句,按需使用guard
语句会提升我们代码的可读性。它可以使你的代码连贯的被执行而不需要将它包在else
块中,它可以使你在紧邻条件判断的地方,处理违规的情况。
检测API可用性
if #available(platform name version,...,*) {
APIs 可用,语句将执行
} else {
APIs 不可用,语句将不执行
}
6. 函数(Functions)
- The Swift Programming Language http://wiki.jikexueyuan.com/project/swift/ ↩