String
Swift 的String和Character类型提供了一个快速的,兼容 Unicode 的方式来处理代码中的文本信息。 创建和操作字符串的语法与 C 语言中字符串操作相似,轻量并且易读。 字符串连接操作只需要简单地通过+号将两个字符串相连即可。 与 Swift 中其他值一样,能否更改字符串的值,取决于其被定义为常量还是变量。
定义
定义一个变量,它的类型是String,值为“xayoung”1
var CoderX = "xayoung"
字符串可变性 (String Mutability)
1 | CoderX += "is a coder!" |
可变性中与OC的不同点
在 Objective-C 和 Cocoa 中,您通过选择两个不同的类(NSString和NSMutableString)来指定该字符串是否可以被修改,Swift 中的字符串是否可以修改仅通过定义的是变量还是常量来决定,实现了多种类型可变性操作的统一。
其他不同点
String 和 NSString 有着良好的互相转换的特性,但是现在 Cocoa 所有的 API 都接受和返回 String 类型。但Swift 中 String 是 struct,相比起 NSObject 的 NSString 类来说,更切合字符串的 “不变” 这一特性。通过配合常量赋值 (let) ,这种不变性在多线程编程时就非常重要了,它从原理上将程序员从内存访问和操作顺序的担忧中解放出来。另外,在不触及 NSString 特有操作和动态特性的时候,使用 String 的方法,在性能上也会有所提升。
String特有的一些特性1
2
3
4let Coder = "xayoung"
for i in Coder.characters {
print(i)
}
枚举
在 Swift 中,枚举类型是一等(first-class)类型。它们采用了很多传统上只被类(class)所支持的特征,例如计算型属性(computed properties),用于提供关于枚举当前值的附加信息, 实例方法(instance methods),用于提供和枚举所代表的值相关联的功能。枚举也可以定义构造函数(initializers)来提供一个初始成员值;可以在原始的实现基础上扩展它们的功能;可以遵守协议(protocols)来提供标准的功能。
定义
1 | enum Eye { |
不像 C 和 Objective-C 一样,Swift 的枚举成员在被创建时不会被赋予一个默认的整数值。在上面的CompassPoints例子中,North,South,East和West不是隐式的等于0,1,2和3。相反的,这些不同的枚举成员在CompassPoint的一种显示定义中拥有各自不同的值。
匹配枚举值和Switch语句
1 | var whichEye = Eye.Left |
如在控制流(Control Flow)中介绍,当考虑一个枚举的成员们时,一个switch语句必须全面。如果忽略了.West这种情况,上面那段代码将无法通过编译,因为它没有考虑到CompassPoint的全部成员。全面性的要求确保了枚举成员不会被意外遗漏。
当不需要匹配每个枚举成员的时候,你可以提供一个默认default分支来涵盖所有未明确被提出的任何成员
类和结构体
类和结构体对比
Swift 中类和结构体有很多共同点。共同处在于:
- 定义属性用于存储值
- 定义方法用于提供功能
- 定义附属脚本用于访问值
- 定义构造器用于生成初始化值
- 通过扩展以增加默认实现的功能
- 符合协议以对某类提供标准功能
与结构体相比,类还有如下的附加功能:
- 继承允许一个类继承另一个类的特征
- 类型转换允许在运行时检查和解释一个类实例的类型
- 解构器允许一个类实例释放任何其所被分配的资源
- 引用计数允许对一个类的多次引用
定义
1 | class VideoMode { |
上边定义了一个名为VideoMode的类,用来描述一个视频显示器的特定模式。这个类包含了四个储存属性变量。第一个是分辨率,它被初始化为一个新的Resolution结构体的实例,具有Resolution的属性类型。新VideoMode实例同时还会初始化其它三个属性,它们分别是,初始值为false(意为“non-interlaced video”)的interlaced,回放帧率初始值为0.0的frameRate和值为可选String的name。name属性会被自动赋予一个默认值nil,意为“没有name值”,因为它是一个可选类型。
1 | struct Scaling { |
属性访问
通过使用点语法(dot syntax),你可以访问实例中所含有的属性。其语法规则是,实例名后面紧跟属性名,两者通过点号(.)连接1
let mouthWidth = faceRadius / Scaling.FaceRadiusToMouthWidthRatio
也可以使用点语法为属性变量赋值:1
Scaling.FaceRadiusToMouthWidthRatio = 50.0
与 Objective-C 语言不同的是,Swift 允许直接设置结构体属性的子属性。上面的最后一个例子,就是直接设置了someVideoMode中resolution属性的width这个子属性,以上操作并不需要重新设置resolution属性。
注意点
在 Swift 中,所有的基本类型:整数(Integer)、浮点数(floating-point)、布尔值(Booleans)、字符串(string)、数组(array)和字典(dictionaries),都是值类型,并且都是以结构体的形式在后台所实现。
在 Swift 中,所有的结构体和枚举都是值类型。这意味着它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制。
而类是引用类型,与值类型不同,引用类型在被赋予到一个变量、常量或者被传递到一个函数时,操作的是引用,其并不是拷贝。因此,引用的是已存在的实例本身而不是其拷贝。
协议
协议(Protocol)用于定义完成某项任务或功能所必须的方法和属性,协议实际上并不提供这些功能或任务的具体实现(Implementation)–而只用来描述这些实现应该是什么样的。类,结构体,枚举通过提供协议所要求的方法,属性的具体实现来采用(adopt)协议。任意能够满足协议要求的类型被称为协议的遵循者。
代理模式1
2
3
4//声明datasource协议,这里需要把FaceVireDataSource变成一个类才能实现的协议,
protocol FaceViewDataSource: class {
func smilinessForFaceView(sender: FaceView) -> Double?
}
实现代理方法1
2//使用操作符??,左侧有值使用它的值,左侧为nil时则使用右侧
let smiliness = dataSource?.smilinessForFaceView(self) ?? 0.0
1 | class HappinessViewController: UIViewController, FaceViewDataSource { |
其他
最后展示截止到课时6,最新的demo效果图。附上代码的github连接:https://github.com/xayoung/CS193P-DemoCode