swift语言的逻辑控制比一般的语言要复杂的多,它在原有的if, while基本上又增加了很多新功能。这些需要仔细研究下
循环结构
在switf中有两种循环:for和while
for 循环
for...in
swift
//简单示例,正常打印5次
var myFirstInt = 0
for i in 1...5 { //正常写法是 for i: Int in 1...5
print(myFirstInt + i)
} //~~ 1, 2, 3, 4, 5
//也可写成这样,用_通配符代替,但这样就取不到每次迭代的值了
for _ in 1...5 {
print(myFirstInt)
}
where子句
swift
//where子句,相当于对每次特殊的值加了一个筛选条件。下例表示:从100个数中取得能整除3的数字
for i in 1...100 where i % 3 == 0 {
print(i)
}
while循环
while...do
swift
// while...do写法
var i = 1
while i < 6 {
print(i)
i += 1
}
repeat...while(do...while)
在其它语言中称为do...while,即先执行一次再看是否再次执行;
swift
var shields = -1;
repeat {
print("Fire blasters!")
} while shields > 0
break和continue
- break:跳出当前整体循环;
- continue:跳过本次循环从头开始,和其它语言的continue意思一样;
一个稍复杂的例子
swift
var shields = 5 //护盾强度
var blastersOverheating = false //武器是否需要冷却
var blasterFireCount = 0 //武器开火次数
var spaceDemonsDestroyed = 0 //击杀怪物的总数量
while shields > 0 {
if spaceDemonsDestroyed == 5 {
print("You beat the game!")
break
}
print(blastersOverheating);
//检查武器是否过热
if blastersOverheating {
print("Blasters are overheated! Cooldown initiated.")
blastersOverheating = false
blasterFireCount = 0
continue //从这就打断了循环,从头开始了
}
//检查开火次数,达到一定3次时,要设置标志位冷却下武器
if blasterFireCount > 2 {
blastersOverheating = true
continue //从这就打断了循环,从头开始了
}
print("Fire blasters!")
blasterFireCount += 1
spaceDemonsDestroyed += 1
}
/*
Fire blasters!
Fire blasters!
Fire blasters!
Blasters are overheated! Cooldown initiated.
Fire blasters!
Fire blasters!
You beat the game!
*/
以上语句都可以混合break和continue一起使用。
选择结构
if 选择
if...else
语法关键字:if、 else以及 else if。
swift
var message: String
var hasPostOffice: Bool = true
if (population < 10000) {
message = "\(population) is a small town!"
} else if (population >= 10000 && population < 50000) {
message = "\(population) is a medium town!"
} else {
message = "\(population) is pretty big!"
}
if case
这种写法完全可以用if...else或switch来代替,属于一个中间品,也是swift语言等有的,用处不大,了解下即可。
swift
let age = 25
if case 18...35 = age {
print("Cool demographic")
}
if case 18...35 = age, age >= 21 {
print("In cool demographic and of drinking age")
}
//~~ Cool demographic
//~~ In cool demographic and of drinking age
guard(if返例)
与if语句相同的是,guard也是基于一个表达式的布尔值去判断一段代码是否该被执行。与if语句不同的是,guard只有在条件不满足的时候才会执行这段代码。你可以把guard近似的看做是Assert,但是你可以优雅的退出而非崩溃。其语法结构如下:
swift
guard expression else {
//语句
//必须包含一个控制语句:return,break,continue或throw。
}
- 如果对表达式求值false,guard则执行代码块内的语句。
- 如果对表达式求值true,guard则从执行中跳过代码块内的语句
swift
guard let username = usernameTextField.text, !username.isEmpty else {
show("用户名不能为空")
return
}
guard let password = passwordTextField.text, !password.isEmpty else {
show("密码不能为空")
return
}
register(username, password)
switch 选择
可以接受整型和枚举,先看一个简单的例子
swift
var statusCode: Int = 420
var errorString: String = "The request failed:"
switch statusCode {
case 400:
errorString += "bad Request, \(statusCode)."
case 500:
errorString += "server error, \(statusCode)."
default:
errorString += "unknown, \(statusCode)."
}
print(errorString) //~~The request failed:unknown, 420.
case组合
如果多个错误码对应同一个错误信息时,可以像下面这样来写
swift
var statusCode: Int = 520
var errorString: String = "The request failed:"
switch statusCode {
case 400:
errorString += "bad Request, \(statusCode)."
case 500, 510, 520, 530:
errorString += "server error, \(statusCode)."
default:
errorString += "unknown, \(statusCode)."
}
print(errorString) //~~The request failed:server error, 520.
case区间
上面采用罗列的方式是比原始简单了一些,但如果有上百个值的话,那么写起来也是很费劲的,所以switch又提供了区间的功能,其格式为:
- intStart...intEnd:如300...600,表示300到600间所有的整数;
swift
var statusCode: Int = 520
switch statusCode {
case 400:
errorString += "bad Request, \(statusCode)."
case 500, 510, 520, 530:
errorString += "server error, \(statusCode)."
case 600...800:
errorString += "nginx error, \(statusCode)."
default:
errorString += "you must fix it."
}
print(errorString) //~~The request failed:server error, 520.
fallthrough
在switch的switch语句中不需要使用break语句,都是隐式设置的。另外它又新增了一个叫fallthrough的关键字,不太好解释其作用,直接看例子可能更直观。
swift
var statusCode: Int = 520
switch statusCode {
case 400:
errorString += "bad Request, \(statusCode)."
case 500, 510, 520, 530:
errorString += "server error, \(statusCode)."
fallthrough
default:
errorString += "you must fix it."
}
print(errorString) //~~The request failed:server error, 520.you must fix it.
另外一个例子
swift
var statusCode: Int = 520
var errorString: String = "The request failed:"
switch statusCode {
case 400:
errorString += "bad Request, \(statusCode)."
case 500, 510, 520, 530:
errorString += "server error, \(statusCode)."
fallthrough
case 600:
errorString += "server error, \(statusCode)."
default:
errorString += "you must fix it."
}
print(errorString) //~~The request failed:server error, 520. server error, 520.
仔细查看以上代码输出:
- break:默认会加在每个case代码块的最末尾,如果匹配就跳出整个switch语句;
- fallthrough:它会无条件执行它下一个case语句,无论是否匹配上;
swift中的switch比其它语言要复杂一点,它可以动态运算。正常case的值可接受String、Int类型的数字以及Enum枚举全可以,需要注意的是在case语句默认带了break
(也可以显式的写break),如果想用continue,则需要用关键字fallthrough来代替。标准写法格式如下面代码所示:
swift
var statusCode: Int = 420
var errorString: String = "The request failed:"
switch statusCode {
//多case值
case 100, 101:
errorString += " Informational, \(statusCode)." //statusCode是一个变量引用
case 204:
errorString += " Successful but no content, \(statusCode)."
fallthrough //代替了continue
default:
errorString = "Unknown error encountered."
break //可以省略
}
值绑定
值绑定能在某个特定分支中把待匹配的值绑定(bind)到本地的常量或变量上。这个常量或变量只能在该分支中使用。可以用var或let来定义。
swift
var statusCode: Int = 900
var errorString: String = "The request failed:"
switch statusCode {
case 100, 101:
errorString += " Informational, \(statusCode)."
case 300...307:
errorString += " Redirection, \(statusCode)."
case 400...417:
errorString += " Client error, \(statusCode)."
case let unknownCode:
errorString = "\(unknownCode) Unknown error encountered."
default :
errorString = "Unknown error encountered." //不会执行
}
print(errorString) //~~900 Unknown error encountered.
这里的unknownCode虽然没有初始化,但默认它的值就是前面swith的值(statusCode),在这个例子中此值为900;所以打印出的结果为"900 Unknown error encountered."。
上述这种写法可以代替default语句。如果同时存在default语句,又如果都能匹配上case,则default不会执行。
where子句
where子句其实就是对值绑定语句的一次细化,表示从已匹配的值中再刨除掉一部分值。
swift
var statusCode: Int = 620
var errorString: String = "The request failed:"
switch statusCode {
case 100, 101:
errorString += " Informational, \(statusCode)."
case 204:
errorString += " Successful but no content, \(statusCode)."
case 300...307:
errorString += " Redirection, \(statusCode)."
//匹配除了前面三个case值外,如果程序运行到这里了,则只匹配:200~300或大于505的值
case let unknownCode where (unknownCode >= 200 && unknownCode < 300) || unknownCode > 505:
errorString = "\(unknownCode) is not a known error code."
default:
errorString = "Unknown error encountered."
}
print(errorString)
//~~statusCode=620时,620 is not a known error code.
//~~statusCode=420时,Unknown error encountered.
元组匹配
正常来讲case只是一个值,在swift中可以指定多个值。在实际中适用于逻辑关联有两个或多个值的情况,其实这种便利也可以用一步计算得出,然后再在switch中匹配计算出来的值。
Swift
let firstErrorCode = 404
let secondErrorCode = 200
let errorCodes = (firstErrorCode, secondErrorCode)
switch errorCodes {
case (404, 404):
print("No items found.")
case (404, _): // _ 表示匹配任意值
print("First item not found.")
case (_, 404):
print("Second item not found.")
default:
print("All items found.")
}
//~~First item not found.
元组操作
swift
//不带名称的元组
let firstErrorCode = 404
let secondErrorCode = 200
let errorCodes = (firstErrorCode, secondErrorCode)
print(errorCodes.0)
print(errorCodes.1)
//带名称的元组
let firstErrorCode = 404
let secondErrorCode = 200
let errorCodes = (first: firstErrorCode, second: secondErrorCode)
print(errorCodes.first)
print(errorCodes.second)
运算符
- 四则运算: +、 -、 *、 \、 %、++、--
- -(负号)
- 赋值运算:=、+=、-=、/=、*=
- 三元运算符:condition ? expression1: expression2
- 位运算:&、 |、 ^、 ~(求反)、 << 、>>
- 关系运算:==、!=、< 、 > 、 <= 、 >=
- 引用运算:=、! 计算两个实例是否指向同一个引用
- 溢出运算:&+、 &-、 &*、 &\(不太建议使用)
- 可空类型运算:??