swift中主要使用下面几种控制流程:
-
for-in
: 对集合进行遍历 -
while|repeat-while
: 和其它语言的一样,repeat-while
就是其它语言中的do-while
语句 - if-else if -else: 条件判断语句,可以在if中顺便声明一下变量什么的,其它没什么可讲的
-
switch
: 这个感觉在swift中功能很强大,可以配合where
对条件进一步过滤,详讲 -
guard-else
: 这个就是if
语句的另一种表示方式,但是其更加的语义化,是控制流程更加的清晰 -
if #available(platform name version, ..., *)
: 检测API可用性
switch
swift中的switch和OC,C,JS不同之处在于,其遇到满足的分支即退出流程,不会再继续,因此 swift中 break
不是必须的
// js 中
const name = 'james'
switch (name) {
case 'james':
console.log('his name is james');
default:
console.log('his name is unknown');
}
// 打印
// his name is james
// his name is unknown
// 更正
const name = 'james'
switch (name) {
case 'james':
console.log('his name is james');
break; // 使用break退出流程
default:
console.log('his name is unknown');
}
// 打印
// his name is james
swift中
// swift 中
let name = "james"
switch name {
case "james":
print("his name is james");
default:
console.log("his name is unknown");
}
// 打印
// his name is james
可以同时匹配多个
JS中匹配多个条件一般使用多个case放在一起的方式,但是swift中一般不这样做,直接使用 ,
分割即可
// js
const char = 'a'
switch (char) {
// 多个case语句放在一起
case 'A':
case 'a':
console.log('the character is a');
break;
default:
console.log('character is not a');
}
// the character is a
swift中:
let char: Character = "a"
switch char {
case "a", "A":
print("the character is a")
default:
print("character is not a")
}
// the character is a
区间匹配
这个比较屌
// swift
let count = 12
let countedThings = "moons orbiting Saturn"
var naturalCount: String
switch count {
case 0:
naturalCount = "no"
// 使用 1..<5 产生一个Range
case 1..<5:
naturalCount = "a few"
case 5..<12:
naturalCount = "serval"
case 12..<100:
naturalCount = "dozens of"
default:
naturalCount = "many"
}
print("there are \(naturalCount) \(countedThings)")
// "There are dozens of moons orbiting Saturn"
元组
使用元组在同一个switch语句中测试多个值。元组中的元素可以使值,也可以是区间,使用下划线(_
)来匹配所有可能的值
// (Int, Int)类型的元组分类图中的点(x, y)
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
print("\(somePoint) 在原点")
case (_, 0):
print("\(somePoint) 在x轴上")
case (0, _):
print("\(somePoint) 在y轴上")
case (-2...2, -2...2):
print("\(somePoint) 在这个区间围成的盒子里面")
default:
print("\(somePoint) 在盒子外面")
}
// (1, 1) 在这个区间围成的盒子里面
值绑定
case 分支允许将匹配的值什么为临时常量或者变量,并且在case分支中使用,这种行为称之为值绑定
// (Int, Int)类型的元组分类图中的点(x, y)
let somePoint = (2, 0)
switch somePoint {
case (let x, 0):
// 上面声明的临时常量可以在case语句中使用
print("\(somePoint) 在x轴上, x的值为 \(x)")
case (0, let y):
print("\(somePoint) 在y轴上, y的值为 \(y)")
case let (x, y):
print("\(somePoint) 在(\(x), \(y))位置")
}
// (2, 0) 在x轴上, x的值为2
case 中配合 where 语句
where
语句可以添加额外的判断:
let somePoint = (1, -1)
switch somePoint {
case let (x, y) where x == y:
print("(\(x), \(y)) 在 x == y 这条直线上")
case let (x, y) where x == -y:
print("(\(x), \(y)) 在 x == -y 这条直线上")
case let (x, y):
print("(\(x), \(y)) 是任意的一个点")
}
// (1, -1) 在 x == -y 这条直线上
复合匹配同样可以包含值绑定。复合匹配里所有的匹配模式,都必须包含相同的值绑定。并且每一个绑定都必须获取到相同类型的值。这保证了,无论复合匹配中的哪个模式发生了匹配,分支体内的代码,都能获取到绑定的值,并且绑定的值都有一样的类型
// (let distance, 0) 匹配在x轴上的值
// (0, let distance) 匹配在y轴上的值
// 2个模式都绑定了 distance
// 并且 distance 在2种模式下,都是整型
// 这意味着分子体内的代码,只要case匹配,都可以获取到distance值
let somePoint = (9, 0)
switch somePoint {
case (let distance, 0), (0, distance):
print("点在轴上, 距离原点位置为 \(distance)")
default:
print("不在轴上")
}
switch 中控制转移语句
改变代码执行顺序,实现代码跳转,swift有5种控制转移语句:
continue
break
fallthrough
return
throw
continue
这个其实和其它语言中的一样, 即停止本次循环,开始下一次循环
let puzzleInput = "great minds think alike"
var puzzleOutput = ""
for char in puzzleInput {
switch char {
case "a", "e", "i", "u", "o", " ":
// 碰到元音或者空格则进入下一次循环
continue
default:
puzzleOutput.append(char)
}
}
print(puzzleOutput) // "grtmndsthnklk"
break
会立即结束整个控制流的执行。因为swift的switch需要包含所有的分支而且不允许有为空的分支,有时为了使意图更明显,需要特意匹配或者忽略某个分支
let numberSymbol: Character = "三" // 简体中文里的数字 3
let numberSymbol: Character = "三" // 简体中文里的数字 3
var possibleIntegerValue: Int?
switch numberSymbol {
case "1", "١", "一", "๑":
possibleIntegerValue = 1
case "2", "٢", "二", "๒":
possibleIntegerValue = 2
case "3", "٣", "三", "๓":
possibleIntegerValue = 3
case "4", "٤", "四", "๔":
possibleIntegerValue = 4
default:
break
}
if let integerValue = possibleIntegerValue {
print("The integer value of \(numberSymbol) is \(integerValue).")
} else {
print("An integer value could not be found for \(numberSymbol).")
}
// 输出 "The integer value of 三 is 3."
fallthrough
swift中,switch语句不会从上一个case分支跳到下一个case分支中。相反,只要匹配到case分支,就结束了。其它语言需要插入 break 结束,是贯穿的,如果想要这种贯穿的特性,swift中使用 fallthrough
关键词
let integerToDescribe = 5
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
description += " a prime number, and also"
// 满足这个条件之后 会继续到下一个分支
fallthrough
default:
description += " an integer."
}
print(description)
// 输出 "The number 5 is a prime number, and also an integer."
guard else 语句
guard
的执行取决于一个表达式的布尔值。
- 我们可以使用
guard
语句来要求条件必须为真,以执行guard
语句后的代码。 - 一个
guard
语句总是有一个else
从句,如果条件不为真,则执行else
从句中的代码 -
else
从句必须转移控制,以退出guard
语句出现的代码段,可以使用return | break | continue | throw
或者调用一二不返回的方法或函数,比如fatalError()
进行退出
func greet(_ person: [String: String]) {
guard let name = person["name"] else {
// 如果person字典中没有 "name" key 就直接退出
return
}
// 如果有 "name" key 则继续执行下面内容
print("hello \(name)")
guard let location = person["location"] else {
print("I hope the weather is nice near you.")
return
}
print("I hope the weather is nice in \(location).")
}
greet(["name": "John"])
// 输出 "Hello John!"
// 输出 "I hope the weather is nice near you."
greet(["name": "Jane", "location": "Cupertino"])
// 输出 "Hello Jane!"
// 输出 "I hope the weather is nice in Cupertino."
上面代码其实等价于:
func greet(_ person: [String: String]) {
if let name = person["name"] {
print("hello \(name)")
} else {
return
}
if let location = person["location"] {
print("I hope the weather is nice in \(location).")
} else {
print("I hope the weather is nice near you.")
return
}
}
检测 API 可用性
这可以确保我们不会再当前部署机器上,不小心地使用了不可用的API
// 还可以指定小版本号 比如 iOS 11.2.6, macOS 10.13.3
if #available(iOS 10, macOS 10.12, *) {
// 在 iOS 使用 iOS 10 的 API, 在 macOS 使用 macOS 10.12 的 API
} else {
// 使用先前版本的 iOS 和 macOS 的 API
}
其语法为:
// platform name 是下列值: iOS,macOS,watchOS 和 tvOS
// * : 是必须要带上的参数,用于指定在所有其它平台中,如果版本号
// 高于你的设备指定的最低版本,if语句的代码将运行
if #available(platform name version, ..., *) {
APIs 可用,语句将执行
} else {
APIs 不可用,语句将不执行
}
网友评论