logo资料库

Swift 编程语言(更新至5.1版本) .pdf

第1页 / 共423页
第2页 / 共423页
第3页 / 共423页
第4页 / 共423页
第5页 / 共423页
第6页 / 共423页
第7页 / 共423页
第8页 / 共423页
资料共423页,剩余部分请下载后查看
欢迎来到Swift的世界
关于 Swift
版本兼容性
Swift 概览
Swift指南
基础内容
常量和变量
声明常量和变量
类型标注
命名常量和变量
输出常量和变量
注释
分号
整数
整数范围
Int
UInt
浮点数
类型安全和类型推断
数值型字面量
数值类型转换
整数转换
整数和浮点数转换
类型别名
布尔值
元组
可选项
nil
If 语句以及强制展开
可选项绑定
隐式展开可选项
错误处理
断言和先决条件
使用断言进行调试
强制先决条件
基本运算符
专门用语
赋值运算符
算术运算符
余数运算符
一元减号运算符
一元加号运算符
组合赋值符号
比较运算符
三元条件运算符
合并空值运算符
区间运算符
闭区间运算符
半开区间运算符
单侧区间
逻辑运算符
逻辑非运算符
逻辑与运算符
逻辑或运算符
混合逻辑运算
显式括号
字符串和字符
字符串字面量
字符串字面量里的特殊字符
扩展字符串分隔符
初始化一个空字符串
字符串可变性
字符串是值类型
操作字符
连接字符串和字符
字符串插值
Unicode
Unicode 标量
扩展字形集群
字符统计
访问和修改字符串
字符串索引
插入和删除
子字符串
字符串比较
字符串和字符相等性
前缀和后缀相等性
字符串的 Unicode 表示法
UTF-8 表示法
UTF-16 表示法
Unicode 标量表示法
集合类型
集合的可变性
数组
数组类型简写语法
创建一个空数组
使用默认值创建数组
通过连接两个数组来创建数组
使用数组字面量创建数组
访问和修改数组
遍历一个数组
合集[1]
Set 类型的哈希值
合集类型语法
创建并初始化一个空合集
使用数组字面量创建合集
访问和修改合集
遍历合集
执行合集操作
基本合集操作
合集成员关系和相等性
字典
字典类型简写语法
创建一个空字典
用字典字面量创建字典
访问和修改字典
遍历字典
译注:
控制流
For-in 循环
While 循环
While
Repeat-While
条件语句
If
Switch
没有隐式贯穿
区间匹配
元组
值绑定
Where
复合情况
控制转移语句
Continue
Break
循环语句中的 Break
Switch 语句里的 Break
Fallthrough
给语句打标签
提前退出
检查API的可用性
函数
定义和调用函数
函数的形式参数和返回值
无形式参数的函数
多形式参数的函数
无返回值的函数
多返回值的函数
可选元组返回类型
隐式返回的函数
函数实际参数标签和形式参数名
指定实际参数标签
省略实际参数标签
默认形式参数值
可变形式参数
输入输出形式参数
函数类型
使用函数类型
函数类型作为形式参数类型
函数类型作为返回类型
内嵌函数
闭包
闭包表达式
Sorted 方法
闭包表达式语法
从语境中推断类型
从单表达式闭包隐式返回
简写的实际参数名
运算符函数
尾随闭包
捕获值
闭包是引用类型
逃逸闭包
自动闭包
枚举
枚举语法
使用 Switch 语句来匹配枚举值
遍历枚举情况(case)
关联值
原始值
隐式指定的原始值
从原始值初始化
递归枚举
类和结构体
类与结构体的对比
定义语法
类与结构体实例
访问属性
结构体类型的成员初始化器
结构体和枚举是值类型
类是引用类型
特征运算符
指针
类和结构体之间的选择
字符串,数组和字典的赋值与拷贝行为
译注
属性
存储属性
常量结构体实例的存储属性
延迟存储属性
存储属性与实例变量
计算属性
简写设置器(setter)声明
缩写读取器(getter)声明
只读计算属性
属性观察者
全局和局部变量
类型属性
类型属性语法
查询和设置类型属性
方法
实例方法
self 属性
在实例方法中修改值类型
在异变方法里指定自身
类型方法
下标
下标的语法
下标用法
下标选项
类型下标
继承
定义一个基类
子类
重写
访问父类的方法、属性和下标脚本
重写方法
重写属性
重写属性的Getter和Setter
重写属性观察器
阻止重写
初始化
为存储属性设置初始化值
初始化器
默认的属性值
自定义初始化
初始化形式参数
形式参数名和实际参数标签
无实际参数标签的初始化器形式参数
可选属性类型
在初始化中分配常量属性
默认初始化器
结构体类型的成员初始化器
值类型的初始化器委托
类的继承和初始化
指定初始化器和便捷初始化器
指定初始化器和便捷初始化器语法
类类型的初始化器委托
规则 1
规则 2
规则 3
两段式初始化
安全检查 1
安全检查 2
安全检查 3
安全检查 4
阶段 1
阶段 2
初始化器的继承和重写
初始化器的自动继承
规则1
规则2
指定和便捷初始化器的实战
可失败初始化器
枚举的可失败初始化器
带有原始值枚举的可失败初始化器
初始化失败的传递
重写可失败初始化器
可失败初始化器 init!
必要初始化器
通过闭包和函数来设置属性的默认值
反初始化
反初始化器原理
应用反初始化器
可选链
可选链代替强制展开
为可选链定义模型类
通过可选链访问属性
通过可选链调用方法
通过可选链访问下标
访问可选类型的下标
链的多层连接
用可选返回值链接方法
错误处理
表示和抛出错误
处理错误
使用抛出函数传递错误
使用 Do-Catch 处理错误
转换错误为可选项
取消错误传递
指定清理操作
类型转换
为类型转换定义类层次
类型检查
向下类型转换
Any 和 AnyObject 的类型转换
内嵌类型
内嵌类型的使用
引用内嵌类型
扩展
扩展的语法
计算属性
初始化器
方法
异变实例方法
下标
内嵌类型
协议
协议的语法
属性要求
方法要求
异变方法要求
初始化器要求
协议初始化器要求的类实现
可失败初始化器要求
将协议作为类型
委托
在扩展里添加协议遵循
有条件地遵循协议
使用扩展声明采纳协议
协议类型的集合
协议继承
类专用的协议
协议组合
协议遵循的检查
可选协议要求
协议扩展
提供默认实现
给协议扩展添加限制
泛型
泛型解决的问题
泛型函数
类型形式参数
命名类型形式参数
泛型类型
扩展一个泛型类型
类型约束
类型约束语法
类型约束的应用
关联类型
关联类型的应用
给关联类型添加约束
在关联类型约束里使用协议
扩展现有类型来指定关联类型
泛型Where分句
带有泛型 Where 分句的扩展
关联类型的泛型 Where 分句
泛型下标
不透明类型
不透明类型解决的问题
返回一个不透明类型
不透明类型和协议类型的区别
自动引用计数
ARC的工作机制
ARC
类实例之间的循环强引用
解决实例之间的循环强引用
弱引用
无主引用
无主引用和隐式展开的可选属性
闭包的循环强引用
解决闭包的循环强引用
定义捕获列表
弱引用和无主引用
内存安全性
了解内存访问冲突
典型的内存访问
输入输出形式参数的访问冲突
在方法中对 self 的访问冲突
属性的访问冲突
访问控制
模块和源文件
访问级别
访问级别的指导准则
框架的访问级别
单元测试目标的访问级别
访问控制语法
自定类型
元组类型
函数类型
枚举类型
原始值和关联值
常量,变量,属性和下标
Getters 和 Setters
初始化器
结构体的默认成员初始化器
协议
协议继承
协议遵循
扩展
扩展中的私有成员
泛型
类型别名
高级运算符
位运算符
位取反运算符
位与运算符
位或运算符
位异或运算符
位左移和右移运算符
无符号整数的移位操作
有符号整型的位移操作
溢出运算符
值溢出
优先级和结合性
运算符方法
前缀和后缀运算符
组合赋值运算符
等价运算符
自定义运算符
自定义中缀运算符的优先级和结合性
基本运算符
cnswift.org-关于 Swift.pdf cnswift.org-版本兼容性.pdf cnswift.org-Swift 概览.pdf cnswift.org-基础内容.pdf cnswift.org-基本运算符.pdf cnswift.org-字符串和字符.pdf cnswift.org-集合类型.pdf cnswift.org-控制流.pdf cnswift.org-函数.pdf cnswift.org-闭包.pdf cnswift.org-枚举.pdf cnswift.org-类和结构体.pdf cnswift.org-属性.pdf cnswift.org-方法.pdf cnswift.org-下标.pdf cnswift.org-继承.pdf cnswift.org-初始化.pdf cnswift.org-反初始化.pdf cnswift.org-可选链.pdf cnswift.org-错误处理.pdf cnswift.org-类型转换.pdf cnswift.org-内嵌类型.pdf cnswift.org-扩展.pdf cnswift.org-协议.pdf cnswift.org-泛型.pdf
cnswift.org-不透明类型.pdf cnswift.org-自动引用计数.pdf cnswift.org-内存安全性.pdf cnswift.org-访问控制.pdf cnswift.org-高级运算符.pdf cnswift.org-关于语言参考.pdf cnswift.org-词汇结构.pdf cnswift.org-类型.pdf cnswift.org-表达式.pdf cnswift.org-特性.pdf cnswift.org-文档修订历史.pdf
cnswift.org/about-swift 关于 Swift Swift 是编写程序的绝佳选择,⽆论是⼿机、电脑还是服务器,任何能跑代码的设备都是如此。它 是⼀门集现代语⾔之⼤成,集结了苹果的⼯程师⽂化精髓以及开源社区多样化于⼀⾝的编程语 ⾔。编译器为专为性能所调优,语⾔专为开发所优化,⼆者绝不互相妥协。 Swift 语⾔还对新的程序员⼗分友好。它是第⼀个⼯业级系统编程语⾔,却⼜像脚本语⾔那样富有 张⼒且⼗分有趣。在 Playground 编写代码并实时查看 Swift 代码运算结果,完全不需要从头编译 然后运⾏软件。 Swift 通过向其他现代编程模式学习,定义了⼤量类来避免常⻅的编程错误: 变量⼀定是在使⽤前初始化的; 数组索引会检查越界错误; 整数会检查溢出; 可选项保证了 nil 值会显式处理; 内存⾃动管理; 错误处理允许从意外错误中恢复控制。 Swift 代码为⼤部分现代硬件编译和优化。语法和基本库都基于指导原则设计,这显然也是你让代 码的最佳⽅式。这使得集安全和速度于⼀⾝的 Swift 适⽤于任何场景,从编写 “Hello, world!”到整 个操作系统,都是上上之选。 Swift ⽤轻量级的语法集合强⼤的类型接⼝和模式匹配,能够把复杂的想法以简洁优雅的形式表 达。得益于此,代码不仅仅更好写了,还变得更加易读和益于优化。 Swift 已经投放市场多年,它还会继续演进,带来更多的新特性和新功能。我们对 Swift 语⾔充满 了信⼼,我们期待着你⽤ Swift 进⾏创作! 1/1
cnswift.org/version-compatibility 版本兼容性 这本书讲述的是 Swift 5.1,它是 Xcode 11 中包含的默认版本。你可以使⽤ Xcode 11 来编译⽤ Swift 5.1、Swift 4.2 或 Swift 4 写的代码。 当你使⽤ Xcode 11 编译 Swift 4 和 Swift 4.2 代码时,⼤部分 Swift 5.1 的功能是可⽤的。也就是 说,下⾯的变更仅对 Swift 5.1 或后续版本⽣效: 返回不透明类型的函数需要 Swift 5.1 运⾏时; try? 表达式并不会为已经返回的可选项引⼊额外的可选性层级; 巨⼤的整数字⾯量初始化表达式会被推断为正确的整数类型。⽐如说, UInt64(0xffff_ffff_ffff_ffff) 会被处理成正确的值⽽不是溢出。 ⽤ Swift 5.1 编写的⽬标可以依赖⽤ Swift 4.2 或 Swift 4 编写的⽬标,反之亦然。也就是说,如果 你有⼀个巨⼤的分成好多个 framework 的项⽬,你可以每次只把⼀个 framework 从 Swift 4 迁移 到 Swift 5.1. 1/1
Swift 概览 依照传统,使⽤新语⾔写的第⼀个程序都应该是在屏幕上打印“Hello,world!”,使⽤ Swift 语⾔, 你可以在⼀⾏中完成。 cnswift.org/a-swift-tour 1 print("Hello, world!") 如果你曾使⽤ C 或者 Objective-C 写代码,那么 Swift 的语法不会让你感到陌⽣——在 Swift 语⾔ 当中,这⼀⾏代码就是⼀个完整的程序!你不需要为每⼀个功能导⼊单独的库⽐如输⼊输出和字 符串处理功能。写在全局范围的代码已被⽤来作为程序的⼊⼝,所以你不再需要 main()函数。同 样,你也不再需要在每句代码后边写分号。 通过向你展⽰各种编程任务,这个概览会给你⾜够的信息来开始使⽤ Swift 进⾏开发。如果觉得这 个概览不够详细,不要担⼼——这个概览所介绍的内容都会在本书的余下章节⾥进⾏详细解释。 为了更好的阅读体验,我们推荐你使用 Xcode 里的 Playground 打开本章内容,Playground 允许你编辑代码并立即看到代码的运算结果。 下载本章的 Playground (官网链接) 简单值 使⽤ let来声明⼀个常量,⽤ var来声明⼀个变量。常量的值在编译时并不要求已知,但是你必须 为其赋值⼀次。这意味着你可以使⽤常量来给⼀个值命名,然后⼀次定义多次使⽤。 1 2 3 var myVariable = 42 myVariable = 50 let myConstant = 42 常量或者变量必须拥有和你赋给它们的值相同的类型。不过,你并不需要总是显式地写出类型。 在声明⼀个常量或者变量的时候直接给它们赋值就可以让编译器推断它们的类型。⽐如上⾯的例 ⼦,编译器就会推断 myVariable是⼀个整型,因为它的初始值是⼀个整型。 如果初始值并不能提供⾜够的信息(或者根本没有提供初始值),就需要在变量的后边写出来 了,⽤冒号分隔。 1 2 3 let implicitInteger = 70 let implicitDouble = 70.0 let explicitDouble: Double = 70 1/20
实验实验 创建一个常量并显式声明类型为 Float ,赋值为 4 值绝对不会隐式地转换为其他类型。如果你需要将⼀个值转换为不同的类型,需要使⽤对应的类 型显⽰地声明。 1 2 3 let label = "The width is " let width = 94 let widthLabel = label + String(width) 实验实验 试试去掉最后一行的转换标记 String ,看看会有怎样的报错? 其实还有⼀种更简单的⽅法来把值加⼊字符串:将值写在圆括号⾥,然后再在圆括号的前边写⼀ 个反斜杠 ( \) ,举个例⼦: 1 2 3 4 let apples = 3 let oranges = 5 let appleSummary = "I have \(apples) apples." let fruitSummary = "I have \(apples + oranges) pieces of fruit." 实验实验 使用 \() 来把一个浮点计算包含进字符串,然后再在一个欢迎语句中插入某人的名字。 为字符串使⽤三个双引号( """ )来⼀次输⼊多⾏内容。只要每⼀⾏的缩进与末尾的引号相同,这 些缩进都会被移除。⽐如说: 1 2 3 4 let quotation = """ I said "I have \(apples) apples." And then I said " I have \(apples + oranges) pieces of fruit." """ 使⽤⽅括号( [])来创建数组或者字典,并且使⽤⽅括号来按照序号或者键访问它们的元素。 var shoppingList = ["catfish", "water", "tulips", "blue paint"] shoppingList[1] = "bottle of water" var occupations = [ "Malcolm": "Captain", "Kaylee": "Mechanic", ] occupations["Jayne"] = "Public Relations" 1 2 3 4 5 6 7 8 2/20
使⽤初始化器语法来创建⼀个空的数组或者字典。 1 2 let emptyArray = [String]() let emptyDictionary = [String: Float]() 如果类型信息能被推断,那么你就可以⽤[]来表⽰空数组,⽤[:]来表⽰空字典。举个栗⼦,当你给 变量设置新的值或者传参数给函数的时候。 1 2 shoppingList = [] occupations = [:] 控制流 使⽤ if和 switch来做逻辑判断,使⽤ for-in, for , while,以及 repeat-while来做循环。使⽤ 圆括号把条件或者循环变量括起来不再是强制的了,不过仍旧需要使⽤花括号来括住代码块。 1 2 3 4 5 6 7 8 9 10 let individualScores = [75, 43, 103, 87, 12] var teamScore = 0 for score in individualScores { if score > 50 { teamScore += 3 } else { teamScore += 1 } } print(teamScore) 在⼀个 if语句当中,条件必须是布尔表达式——这意味着⽐如说 if score {...}将会报错,不再隐式 地与零做计算了。 你可以⼀起使⽤ if和 let来操作那些可能会丢失的值。这些值使⽤可选项表⽰。可选的值包括了⼀ 个值或者⼀个 nil来表⽰值不存在。在⼀个值的类型后边使⽤问号( ?)来把某个值标记为可选 的。 var optionalString: String? = "Hello" print(optionalString == nil) var optionalName: String? = "John Appleseed" var greeting = "Hello!" if let name = optionalName { greeting = "Hello, \(name)" } 1 2 3 4 5 6 7 8 3/20
实验实验 把 optionalName的值改为 nil。你得到的 greeting 是什么内容?添加 else分句,如果 optionalName为 nil就设置不同的内容给 greeting。 如果可选项的值为 nil,则条件为 false并且花括号⾥的代码将会被跳过。否则,可选项的值就会被 展开且赋给 let后边声明的常量,这样会让展开的值对花括号内的代码可⽤。 另⼀种处理可选值的⽅法是使⽤ ?? 运算符提供默认值。如果可选值丢失,默认值就会使⽤。 1 2 3 let nickName: String? = nil let fullName: String = "John Appleseed" let informalGreeting = "Hi \(nickName ?? fullName)" Switch 选择语句⽀持任意类型的数据和各种类型的⽐较操作——它不再限制于整型和测试相等 上。 1 2 3 4 5 6 7 8 9 10 11 let vegetable = "red pepper" switch vegetable { case "celery": print("Add some raisins and make ants on a log." ) case "cucumber", "watercress": print("That would make a good tea sandwich." ) case let x where x.hasSuffix("pepper"): print("Is it a spicy \(x)?") default: print("Everything tastes good in soup.") } 实验实验 尝试去掉 default选项。会得到什么样的报错? 注意 let 可以⽤在模式⾥来指定匹配的值到⼀个常量当中。 在执⾏完 switch 语句⾥匹配到的 case 之后,程序就会从 switch 语句中退出。执⾏并不会继续跳 到下⼀个 case ⾥,所以完全没有必要显式地在每⼀个 case 后都标记 break 。 你可以使⽤ for-in来遍历字典中的项⽬,这需要提供⼀对变量名来储存键值对。字典使⽤⽆序集 合,所以键值的遍历也是⽆序的。 4/20
分享到:
收藏