Swift 3.0之一、 入门
1. 常量和变量
let
声明常量, var
声明变量。
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0
多个常量或者变量声明用逗号分隔:
var x = 0.0, y = 0.0, z = 0.0
2. 类型标注
冒号加空格 + 类型名
var welcomeMessage: String
多个常量或者变量声明用逗号分隔:
var red, green, blue: Double
3. 命名常量和变量
命名规范:常量和变量的名字不能包含空白字符、数学符号、箭头、保留的(或者无效的)Unicode 码位、连线和制表符。也不能以数字开头,尽管数字几乎可以使用在名字其他的任何地方。
let π = 3.14159
let 你好 = "你好世界"
let 🐶🐮 = "dogcow"
4. 输出常量和变量
print(常量或变量名)
print("The current value of friendlyWelcome
is \(常量或变量名)")
5. 注释
1. // 这是一个注释
2. /* 这也是
一个
注释 */
3. /* 这是第一个多行注释的开头
/* 这是第二个嵌套在内的注释块 */
这是第一个注释块的结尾*/
6. 分号
单行多个语句时用来分隔,其它情况可省略。
let cat = "🐱"; print(cat)
7. 整数
分为有符号(正负数和0)和无符号(正数和0)整数
Swift提供了8,16,32 和 64位编码的有符号和无符号整数
- 有符号:
Int8
Int16
Int32
Int64
- 无符号:
UInt8
UInt16
UInt32
UInt64
整数范围
通过 min
和 max
属性来访问每个整数类型的最小值和最大值:
let minValue = UInt8.min // 最小值是 0, 值的类型是 UInt8
let maxValue = UInt8.max // 最大值是 255, 值得类型是 UInt8
Int
32 位机器上是Int32
, 64 位机器上是Int64
.
UInt
32 位机器上是UInt32
, 64 位机器上是UInt64
.
8. 浮点数
- Double代表 64 位的浮点数。
- Float 代表 32 位的浮点数
Double
有至少 15 位数字的精度,而Float
的精度只有 6 位。
9. 类型安全和类型推断
类型安全:编译代码的时候会进行类型检查,任何不匹配的类型都会被标记为错误。
类型推断:未进行类型声明,自动推断出合适的类型。如:
let meaningOfLife = 42 // meaningOfLife 被推断为 Int 类型
let pi = 3.14159 // pi 被推断为 Double 类型
let anotherPi = 3 + 0.14159 // anotherPi 被推断为 Double 类型
10. 数值型字面量
- 十进制数,没有前缀
- 二进制数,前缀:
0b
- 八进制数,前缀:
0o
- 十六进制数,前缀:
0x
示例分别为:
let decimalInteger = 17
let binaryInteger = 0b10001 // 17 in binary notation
let octalInteger = 0o21 // 17 in octal notation
let hexadecimalInteger = 0x11 // 17 in hexadecimal notation
整数和浮点数都可以添加额外的零或者添加下划线来增加代码的可读性:
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
11. 数值类型转换
整数转换
不同整数的类型在变量和常量中存储的数字范围是不同的。Int8
类型的常量或变量可以存储的数字范围是 -128 ~ 127,而 UInt8
类型的常量或者变量能存储的数字范围是 0~255 。如果数字超出了常量或者变量可存储的范围,编译的时候就会报错:
let cannotBeNegative: UInt8 = -1
// UInt8 类型不能存负数,编译会报错。
let tooBig: Int8 = Int8.max + 1
// Int8 类型个不能存大于其最大值的数字,所以编译也会报错
不同类型的整型原则上无法直接相加,需要转换为同一类型,如:
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
整数和浮点数转换
let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi 此时为 3.14159, 并未推断为 Double 类型。
let integerPi = Int(pi)
// integerPi 此时为 3, 并被推断为 Int 类型。
注意:浮点数->整数类型时,数值会被截断。如: 4.75 会变成 4,-3.9 会变为 -3。
12. 类型别名
给系统类型换个你觉得爽的名字:
typealias AudioSample = UInt16
// 此时 AudioSample 和 UInt16等价,如用它初始化下面的变量 maxAmplitudeFound:
var maxAmplitudeFound = AudioSample.max
13. 布尔值(Bool)
Swift布尔值是两个常量值,true
和 false
,声明一个Bool值:
let orangesAreOrange = true
let turnipsAreDelicious = false
Bool常用语if语句,如:
if turnipsAreDelicious {
print("Mmm, tasty turnips!")
} else {
print("Eww, turnips are horrible.")
}
注意:非Bool值不可以作为if语句的判断条件
14. 元组
圆括号组装一堆类型,称之为元组。
元组内的值可以是任何类型,而且可以不必是同一类型。如:
常量http404Error
是 (Int, String)
类型, 值是(404, "Not Found")
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"
15. 可选项
可选项,允许一个常量或变量值为nil
。
nil
声明一个可选变量,并置nil。
var serverResponseCode: Int? = 404
// serverResponseCode 有值,是404。
serverResponseCode = nil
// serverResponseCode 此时为nil
如果定义的可选变量没有提供默认值,变量会被自动设置成nil
。
var surveyAnswer: String?
// surveyAnswer 被自动设置成 nil
注意:非可选变量或常量不可以置nil
If 语句以及强制展开
原理: 如果一个可选项有值,它就“不等于” nil
,所以if
语句派上用场:
if convertedNumber != nil {
print("convertedNumber contains some integer value.")
}
// 打印结果: "convertedNumber contains some integer value."
一旦你确定可选项中包含值,可以在可选项名字后以一个感叹号强制展开,如:
if convertedNumber != nil {
print("convertedNumber has an integer value of \(convertedNumber!).")
}
// 打印结果: "convertedNumber has an integer value of 123."
注意:强制展开
nil
会导致运行错误,因此要确保其有值。
可选项绑定
上面的例子通常用下面的绑定写法代替:
if let actualNumber = Int(possibleNumber) {
print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
} else {
print("\'\(possibleNumber)\' could not be converted to an integer")
}
// 打印结果: "'123' has an integer value of 123"
多个判断条件用逗号分隔,下面两个例子是等价的:
if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
}
// 打印结果: "4 < 42 < 100"
if let firstNumber = Int("4") {
if let secondNumber = Int("42") {
if firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
}
}
}
// 打印结果: "4 < 42 < 100"
注意:使用
if
语句创建的常量和变量只在if
语句的函数体内有效。但是,在guard
语句中创建的常量和变量在guard
语句后的代码中仍然可用。
叹号展开可选项
有时在一些程序结构中变量一旦被设定值之后,就会一直拥有值,因此不必每次访问的时候都进行判断然后展开。这种一定能被访问到值的变量,定义时可以采用如(String!
)而非问号(String?
) 来初始化。如:
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // 直接访问assumedString,不需要叹号
普通的可选项必须用“变量或常量名 + 叹号”的方式或者可选项绑定的方式访问:
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // possibleString 后需要接一个叹号
注意:若变量可能为nil,则不建议使用叹号展开可选项
16. 错误处理
使用错误处理机制来为错误状况负责:
func canThrowAnError() throws {
// 函数名括号后添加“throws”关键字,表明此函数或许会抛出异常。
}
异常有抛出,相应地,就有捕获(使用do{}...catch{}
语句):
do {
try canThrowAnError()
// 使用“try”关键字 尝试捕获或许会抛出异常的函数
} catch {
// 捕获异常后,做后续处理
}
举个栗子:
func makeASandwich() throws {
// 此函数是指要做三明治,但有可能过程没那么顺利,抛出异常。
}
do {
try makeASandwich() // 尝试做三明治
eatASandwich() // 做好了,没异常,直接吃掉。
} catch Error.OutOfCleanDishes { // 异常情况: 盘子不干净
washDishes() // 洗盘子
} catch Error.MissingIngredients(let ingredients) { // 异常情况: 缺少佐料
buyGroceries(ingredients) // 去买佐料
}
注意:若异常条件都满足,则都执行相应后续处理。更详细使用方式,后续介绍。
17.断言
想提前终止程序进行调试时,使用断言。
使用断言进行调试
使用全局函数 assert(_:_:)
函数来写断言:
let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
// 此函数第一个参数为Bool,第二个参数(也可以省略)为String。
// 如果Bool值为false,则程序终止,输出第二个参数的String值。
// 因此,如果年龄age为负数,程序终止,输出后面字符串。
注意: Xcode以默认发布配置编译到app时,断言失效。
什么时候常使用断言
- 判定数组越界
- 判定合法值
- 判定可选项非空
断言是作为调试的有效手段。