子中的intb被定义为"隐式解析可选类型",它还是可选类型,可以赋值为nil,也可以可选绑定。
在使用隐式解析可选类型时,不用加!,系统会自动解析,就从可选类型变为它本身的类型,可以把隐式解析可选类型当做一个可以自动解析的可选类型
var intb:Int! = 4 // 隐式解析可选类型
intb = nil // 赋值为nil
if let intc = intb { // 可选绑定
print(intc + intb)
}
强制解析
当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号(!)来获取值,这被称为可选值的强制解析。强制解析一定要确保有值,否则会程序崩溃。
nil
在oc中代表一个空指针(指向不存在对象的指针)。仅仅限于对象
在swift中代表一个可选值的状态为没有值,它是一个确定的值,用来表示值缺失,不仅限于对象
可选绑定
使用可选绑定(optional binding)来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变量。可选绑定可以用在if和while语句中,这条语句不仅可以用来判断可选类型中是否有值,同时可以将可选类型中的值赋给一个常量或者变量,赋给的常量或者变量的作用域只是在if紧跟的大括号内,赋值失败,赋值成功、失败作为if判断的Bool条件
let string : String? = nil
if let constantName = string { // 这里的string必须为可选类型,不然会报错
print(constantName)
} else {
print(constantName) // 错误: 超出constantName作用域
}
使用断言进行调试
断言会在运行时判断一个逻辑条件是否为true
你可以使用全局assert(_:_file:line:)函数来写一个断言。向这个函数传入一个结果为true或者false的表达式以及一条信息,当表达式的结果为false的时候这条信息会被显示:
let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
// 因为 age < 0,所以断言会触发
在这个例子中,只有age >= 0为true的时候,即age的值非负的时候,代码才会继续执行。如果age的值是负数,就像代码中那样,age >= 0为false,断言被触发,终止应用。
使用场景:
- 整数类型的下标索引被传入一个自定义下标实现,但是下标索引值可能太小或者太大。
- 需要给函数传入一个值,但是非法的值可能导致函数不能正常执行。
- 一个可选值现在是nil,但是后面的代码运行需要一个非nil值。
运算符
Swift 支持大部分标准 C 语言的运算符,且改进许多特性来减少常规编码错误。如:赋值符(=)不返回值,以防止把想要判断相等运算符(==)的地方写成赋值符导致的错误
算术运算符(+,-,*,/,%等)会检测并不允许值溢出,以此来避免保存变量时由于变量大于或小于其类型所能承载的范围时导致的异常结果
区别于 C 语言,在 Swift 中你可以对浮点数进行取余运算(%),Swift 还提供了 C 语言没有的表达两数之间的值的区间运算符(a..<b 和 a...b),这方便我们表达一个区间内的数值。
8 % 2.5 // 等于 0.5 3个2.5 还剩余一个0.5
当元组中的值可以比较时,你也可以使用这些运算符来比较它们的大小。例如,因为 Int 和 String 类型的值可以比较,所以类型为 (Int, String) 的元组也可以被比较。相反,Bool 不能被比较,也意味着存有布尔类型的元组不能被比较。
比较元组大小会按照从左到右、逐值比较的方式,直到发现有两个值不等时停止。如果所有的值都相等,那么这一对元组我们就称它们是相等的。例如:
(1, "zebra") < (2, "apple") // true,因为 1 小于 2
(3, "apple") < (3, "bird") // true,因为 3 等于 3,但是 apple 小于 bird
(4, "dog") == (4, "dog") // true,因为 4 等于 4,dog 等于 dog
注意: Swift 标准库只能比较七个以内元素的元组比较函数。如果你的元组元素超过七个时,你需要自己实现比较运算符。
空合运算符
空合运算符(a ?? b)将对可选类型 a 进行空判断,如果 a 包含一个值就进行解封,否则就返回一个默认值 b。表达式 a 必须是 Optional 类型。默认值 b 的类型必须要和 a 存储值的类型保持一致。
注意: 如果 a 为非空值(non-nil),那么值 b 将不会被计算。这也就是所谓的短路求值,短路运算符一般有:&&、||,其原理是:当有多个表达式时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值
闭区间运算符
闭区间运算符(a...b)定义一个包含从 a 到 b(包括 a 和 b)的所有值的区间。a 的值不能超过 b
半开区间运算符
半开区间(a..<b)定义一个从 a 到 b 但不包括 b 的区间
逻辑运算符
逻辑与 或 非运算符的操作数只能是bool类型,不能是整型等等。Swift 逻辑操作符 && 和 || 是左结合的
字符串
定义空字符串
var emptyString = "" // 空字符串字面量
var anotherEmptyString = String() // 初始化方法
// 两个字符串均为空并等价。
您可以通过检查其Bool类型的isEmpty属性来判断该字符串是否为空:
if emptyString.isEmpty {
print("Nothing to see here")
}
字符串是值类型(Strings Are Value Types)
Swift 的String类型是值类型。 如果您创建了一个新的字符串,那么当其进行常量、变量赋值操作,或在函数/方法中传递时,会进行值拷贝。 任何情况下,都会对已有字符串值创建新副本,并对该新副本进行传递或赋值操作
在实际编译时,Swift 编译器会优化字符串的使用,使实际的复制只发生在绝对必要的情况下,这意味着您将字符串作为值类型的同时可以获得极高的性能。
另外,通过标明一个Character类型并用字符字面量进行赋值,可以建立一个独立的字符常量或变量:
let exclamationMark: Character = "!" // 不能用'',必须双引号,而且必须指定为Character类型,否则会推断为string类型
注意: 可扩展的字符群集可以组成一个或者多个 Unicode 标量。这意味着不同的字符以及相同字符的不同表示方式可能需要不同数量的内存空间来存储。所以 Swift 中的字符在一个字符串中并不一定占用相同的内存空间数量。因此在没有获取字符串的可扩展的字符群的范围时候,就不能计算出字符串的字符数量。如果您正在处理一个长字符串,需要注意characters属性必须遍历全部的 Unicode 标量,来确定字符串的字符数量。
另外需要注意的是通过characters属性返回的字符数量并不总是与包含相同字符的NSString的lengt