之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习、总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询用。详细可以参考the-swift-programming-language-in-chinese,或者苹果官方英文版文档
当前版本是swift2.2
print函数
函数原型
print(items, separator: String, terminator: String)
参数:
- items:要打印的变量,或常量
- separator:多个item参数之间的间隔符
- terminator:打印的末尾可以增加一个字符串
weak与unowned
在OC中,当__weak指向的对象被释放时,weak指向nil,在swift中也一样,那么weak修饰的变量应该为可选类型。
unowned相当于oc中的_unsafe_unretained,对象释放后后指向一块固定的内存。
- weak用在:当self对象优先于block调用时
- unowned:当self对象在block调用时不会被释放
swift中提供了捕获列表更优雅的解决了这个问题
注释
支持 //
注释和块注释/**/
,还支持注释嵌套(C语言不支持):
/* 这是第一个多行注释的开头
/* 这是第二个被嵌套的多行注释 */
这是第一个多行注释的结尾 */
类型转换
一百万可以两种表示:1000000或1_000_000
let value = 3 + 0.14159 // value最终类型为Double类型,原始值3没有显式声明类型,0.14159默认为Double类型
而下面的例子,则不可以:
let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = three + pointOneFourOneFiveNine // 错误
let integerPi = Int(pi)
// integerPi 等于 3,所以被推测为 Int 类型。浮点值会被截断。也就是说4.75会变成4,-3.9会变成-3。
不同类型变量不支持隐式转换.在下面的例子中,常量twoThousand是UInt16类型,然而常量one是UInt8类型。它们不能直接相加,因为它们类型不同。所以要调用UInt16(one)来创建一个新的UInt16数字并用one的值来初始化,然后使用这个新数字来计算:
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
现在两个数字的类型都是UInt16,可以进行相加。目标常量twoThousandAndOne的类型被推断为UInt16,因为它是两个UInt16值的和。
UInt16(one)是调用 Swift 构造器并传入一个初始值的默认方法。在语言内部,UInt16有一个构造器,可以接受一个UInt8类型的值,所以这个构造器可以用现有的UInt8来创建一个新的UInt16。注意,你并不能传入任意类型的值,只能传入UInt16内部有对应构造器的值。不过你可以扩展现有的类型来让它可以接收其他类型的值
float和double类型也不能直接相加
类型别名
typealias AudioSample = UInt16
定义了一个类型别名之后,你可以在任何使用原始名的地方使用别名:
var maxAmplitudeFound = AudioSample.min // 值为0
元组
把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。
你可以将一个元组的内容分解(decompose)成单独的常量和变量,然后你就可以正常使用它们了:
let http404Error = (404, "Not Found")
let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)") // 输出 "The status code is 404"
print("The status message is \(statusMessage)") // 输出 "The status message is Not Found"
如果你只需要一部分元组值,分解的时候可以把要忽略的部分用下划线(_)标记:
let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)") // 输出 "The status code is 404"
此外,你还可以通过下标来访问元组中的单个元素,下标从零开始:
print("The status code is \(http404Error.0)") // 输出 "The status code is 404"
print("The status message is \(http404Error.1)") // 输出 "The status message is Not Found"
你可以在定义元组的时候给单个元素命名:
let http200Status = (statusCode: 200, description: "OK")
给元组中的元素命名后,你可以通过名字来获取这些元素的值:
print("The status code is \(http200Status.statusCode)") // 输出 "The status code is 200"
print("The status message is \(http200Status.description)") // 输出 "The status message is OK"
元组在临时组织值的时候很有用,但是并不适合创建复杂的数据结构。如果你的数据结构并不是临时使用,请使用类或者结构体而不是元组。请参考类和结构体。
可选类型
可选类型不能像普通类型一样使用,比如两个可选类型相加会报错,不只相加,加减乘除等等
如果你声明一个可选常量或者变量但是没有赋值,它们会自动被设置为nil:
var surveyAnswer: String? // surveyAnswer 被自动设置为 nil
一个变量或常量被定义为可选类型,那么它就不是原来的类型了,而是可选类型,只有解析后为有值才可以回到原来的类型。
let inta:Int? = 3
let intb:Int! = 4
print(inta + intb) // 错误,正确应该是inta! + intb
if inta != nil {
print(inta + intb) // 错误,正确应该是inta! + intb
}
if let intc = inta {
print(intc + intb) // 可选绑定可以当非可选类型使用
}
隐式解析可选类型
一个可选类型总会有值,这种类型的可选状态被定义为隐式解析可选类型
比如例