MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Swift控制流语句全解析

2022-03-073.0k 阅读

if 语句

在Swift编程中,if语句是最基础的条件判断控制流。它基于一个布尔表达式的结果来决定是否执行特定的代码块。如果布尔表达式的值为true,则执行紧跟在if语句后的代码块;若为false,则跳过该代码块。

基本语法

if booleanExpression {
    // 当booleanExpression为true时执行的代码
}

例如,我们判断一个整数是否大于10:

let number = 15
if number > 10 {
    print("\(number)大于10")
}

在上述代码中,number > 10是布尔表达式。由于number的值为15,该表达式结果为true,因此会打印出15大于10

if - else 结构

if - else结构允许我们在布尔表达式为truefalse时分别执行不同的代码块。

if booleanExpression {
    // 当booleanExpression为true时执行的代码
} else {
    // 当booleanExpression为false时执行的代码
}

示例如下,判断一个数是否为偶数:

let num = 7
if num % 2 == 0 {
    print("\(num)是偶数")
} else {
    print("\(num)是奇数")
}

这里num % 2 == 0是布尔表达式。因为7除以2的余数不为0,表达式为false,所以会打印7是奇数

if - else if - else 链

当需要基于多个条件进行判断时,可以使用if - else if - else链。它会按顺序依次检查每个ifelse if后的布尔表达式,一旦找到一个为true的表达式,就执行其对应的代码块,然后跳过整个if - else if - else链。

if booleanExpression1 {
    // 当booleanExpression1为true时执行的代码
} else if booleanExpression2 {
    // 当booleanExpression2为true时执行的代码
} else {
    // 当所有布尔表达式都为false时执行的代码
}

例如,根据一个学生的考试成绩给出相应评价:

let score = 85
if score >= 90 {
    print("优秀")
} else if score >= 80 {
    print("良好")
} else if score >= 60 {
    print("及格")
} else {
    print("不及格")
}

此例中,score为85,所以会打印良好

switch 语句

switch语句是Swift中另一种重要的条件控制流,它可以基于一个值与多个可能情况进行匹配,并执行匹配到的相应代码块。与if语句不同,switch语句更适合处理多个离散值的情况。

基本语法

switch valueToMatch {
case value1:
    // 当valueToMatch等于value1时执行的代码
case value2:
    // 当valueToMatch等于value2时执行的代码
default:
    // 当valueToMatch不匹配任何case时执行的代码
}

比如,根据一个整数来打印对应的星期几:

let day = 3
switch day {
case 1:
    print("星期一")
case 2:
    print("星期二")
case 3:
    print("星期三")
case 4:
    print("星期四")
case 5:
    print("星期五")
case 6:
    print("星期六")
case 7:
    print("星期日")
default:
    print("无效的数字")
}

这里day的值为3,所以会打印星期三

匹配范围

switch语句不仅可以匹配单个值,还能匹配值的范围。

let age = 25
switch age {
case 0...12:
    print("儿童")
case 13...19:
    print("青少年")
case 20...39:
    print("年轻人")
case 40...59:
    print("中年人")
default:
    print("老年人")
}

因为age为25,处于20到39这个范围,所以会打印年轻人

元组匹配

switch语句还支持元组匹配,即同时匹配多个值。

let point = (2, 3)
switch point {
case (0, 0):
    print("原点")
case (_, 0):
    print("x轴上的点")
case (0, _):
    print("y轴上的点")
case let (x, y) where x == y:
    print("在y = x直线上的点,坐标为(\(x), \(y))")
default:
    print("其他点")
}

此例中,point为(2, 3),匹配default分支,会打印其他点。其中(_, 0)表示匹配y坐标为0的任意点,where关键字用于添加额外的条件。

区间匹配

switch语句中,还可以使用区间匹配来处理更复杂的情况。例如,判断一个数字是否在某个区间内:

let numValue = 55
switch numValue {
case 0..<10:
    print("0到9之间(不包括10)")
case 10...20:
    print("10到20之间(包括10和20)")
case 21...30:
    print("21到30之间(包括21和30)")
default:
    print("不在上述区间内")
}

由于numValue为55,所以会打印不在上述区间内

for - in 循环

for - in循环是Swift中用于遍历序列的控制流,例如数组、字典、范围等。它会针对序列中的每个元素执行一次代码块。

遍历数组

let fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits {
    print(fruit)
}

上述代码会依次打印出数组fruits中的每个元素,即苹果香蕉橙子

遍历字典

let person = ["name": "张三", "age": 28]
for (key, value) in person {
    print("\(key): \(value)")
}

这里会打印出name: 张三age: 28。在遍历字典时,我们可以同时获取键和值。

遍历范围

for i in 1...5 {
    print(i)
}

此代码会打印出1到5的整数,包括1和5。这里使用的是闭区间1...5。如果使用半开区间1..<5,则会打印1到4的整数,不包括5。

while 循环

while循环会在给定的布尔表达式为true时,重复执行代码块。

基本语法

while booleanExpression {
    // 当booleanExpression为true时重复执行的代码
}

例如,打印1到10的数字:

var num = 1
while num <= 10 {
    print(num)
    num += 1
}

这里num <= 10是布尔表达式,只要该表达式为true,就会执行代码块,打印num的值并将其加1,直到num大于10时停止循环。

repeat - while 循环

repeat - while循环与while循环类似,但它会先执行一次代码块,然后再检查布尔表达式。这意味着无论布尔表达式最初的值如何,代码块至少会执行一次。

基本语法

repeat {
    // 先执行的代码
} while booleanExpression

例如,让用户输入一个数字,直到输入的数字大于10:

var input = 0
repeat {
    print("请输入一个大于10的数字:")
    if let userInput = readLine(), let number = Int(userInput) {
        input = number
    }
} while input <= 10

在这个例子中,程序会先提示用户输入数字,然后检查输入的数字是否大于10。如果不大于10,会再次提示用户输入,直到输入的数字满足条件。

控制转移语句

break

break语句用于立即终止当前循环(forwhilerepeat - while)或switch语句的执行,并将控制权转移到这些语句之后的下一行代码。

在循环中使用break

for i in 1...10 {
    if i == 5 {
        break
    }
    print(i)
}

此代码会打印1到4,当i等于5时,break语句终止循环,所以不会打印5到10。

switch语句中使用break

let char = 'c'
switch char {
case 'a':
    print("匹配到a")
    break
case 'b':
    print("匹配到b")
    break
case 'c':
    print("匹配到c")
    break
default:
    print("未匹配到")
}

这里当匹配到'c'时,break语句确保不会执行default分支。

continue

continue语句用于跳过当前循环迭代中剩余的代码,并立即开始下一次迭代。

for i in 1...10 {
    if i % 2 == 0 {
        continue
    }
    print(i)
}

此代码会打印1到10中的奇数。当i是偶数时,continue语句会跳过打印操作,直接开始下一次循环。

fallthrough

在Swift的switch语句中,默认情况下,一旦匹配到一个case分支,就会执行该分支的代码,然后跳出switch语句。而fallthrough关键字可以打破这种默认行为,使程序继续执行下一个case分支的代码,即使下一个case分支并不匹配。

let numCase = 2
switch numCase {
case 1:
    print("数字1")
    fallthrough
case 2:
    print("数字2")
    fallthrough
case 3:
    print("数字3")
default:
    print("其他数字")
}

这里numCase的值为2,会先打印数字2,由于使用了fallthrough,还会继续打印数字3

guard

guard语句用于在代码执行进入某个范围之前,对一个条件进行检查。如果条件为falseguard语句会执行else分支中的代码,通常会包含returnbreakcontinuethrow语句,以提前结束当前范围的执行。

func greet(_ name: String?) {
    guard let unwrappedName = name else {
        print("名字为空")
        return
    }
    print("你好, \(unwrappedName)!")
}
greet(nil)
greet("李四")

在上述greet函数中,guard语句检查name是否为nil。如果namenil,会打印名字为空并返回;如果name不为nil,则解包name并打印问候语。

嵌套控制流

在Swift中,控制流语句可以相互嵌套,例如在一个for循环中嵌套另一个for循环,或者在if语句中嵌套switch语句等。

嵌套for循环

for i in 1...3 {
    for j in 1...3 {
        print("(\(i), \(j))")
    }
}

上述代码会打印出(1, 1)、(1, 2)、(1, 3)、(2, 1)、(2, 2)、(2, 3)、(3, 1)、(3, 2)、(3, 3)。外层for循环每执行一次,内层for循环会完整执行一轮。

在if中嵌套switch

let numIfSwitch = 2
if numIfSwitch > 0 {
    switch numIfSwitch {
    case 1:
        print("数字1")
    case 2:
        print("数字2")
    default:
        print("其他正数")
    }
} else {
    print("非正数")
}

这里先通过if语句判断numIfSwitch是否大于0,如果大于0,再通过switch语句进一步判断其具体值。

控制流与函数

控制流语句在函数中经常被使用,用于根据不同的条件执行不同的逻辑。

函数中的if - else

func calculate(_ a: Int, _ b: Int, _ operation: String) -> Int? {
    if operation == "+" {
        return a + b
    } else if operation == "-" {
        return a - b
    } else if operation == "*" {
        return a * b
    } else if operation == "/" {
        if b != 0 {
            return a / b
        } else {
            print("除数不能为0")
            return nil
        }
    } else {
        print("不支持的操作")
        return nil
    }
}
let result = calculate(5, 3, "+")
if let finalResult = result {
    print("计算结果: \(finalResult)")
}

calculate函数中,通过if - else语句根据不同的操作符执行相应的运算。

函数中的循环

func sumOfNumbers(from start: Int, to end: Int) -> Int {
    var sum = 0
    for i in start...end {
        sum += i
    }
    return sum
}
let sum = sumOfNumbers(from: 1, to: 10)
print("1到10的和: \(sum)")

sumOfNumbers函数使用for循环计算从startend的所有整数的和。

控制流与闭包

闭包中也可以使用控制流语句,以实现更复杂的逻辑。

let numbers = [1, 2, 3, 4, 5]
let evenNumbers = numbers.filter { number in
    if number % 2 == 0 {
        return true
    } else {
        return false
    }
}
print(evenNumbers)

在上述代码中,filter方法接受一个闭包作为参数。闭包中使用if - else语句判断每个数字是否为偶数,从而过滤出数组中的偶数。

控制流在实际项目中的应用

在实际的Swift项目开发中,控制流语句无处不在。比如在一个游戏开发项目中,可能会使用for - in循环遍历游戏场景中的所有物体,使用if语句判断玩家是否击中目标,使用while循环来更新游戏状态等。

游戏场景物体遍历

class GameObject {
    var name: String
    init(name: String) {
        self.name = name
    }
}
let gameObjects = [GameObject(name: "敌人1"), GameObject(name: "金币1"), GameObject(name: "障碍物1")]
for object in gameObjects {
    if object.name.hasPrefix("敌人") {
        print("发现敌人: \(object.name)")
    } else if object.name.hasPrefix("金币") {
        print("发现金币: \(object.name)")
    } else {
        print("发现障碍物: \(object.name)")
    }
}

这里通过for - in循环遍历游戏场景中的物体,并使用if - else if - else语句对不同类型的物体进行分类处理。

游戏状态更新

var gameOver = false
var playerHealth = 100
while!gameOver {
    // 模拟受到伤害
    playerHealth -= 10
    if playerHealth <= 0 {
        gameOver = true
        print("游戏结束")
    } else {
        print("玩家生命值: \(playerHealth)")
    }
}

在这个简单的游戏状态更新示例中,while循环不断检查游戏是否结束,根据玩家生命值的变化来决定游戏是否继续。

控制流的性能优化

在使用控制流语句时,合理的优化可以提高程序的性能。

减少不必要的判断

例如,在if - else if - else链中,将最有可能为true的条件放在前面,这样可以减少不必要的判断次数。

let userRole = "admin"
if userRole == "admin" {
    // 管理员权限操作
    print("执行管理员操作")
} else if userRole == "user" {
    // 普通用户操作
    print("执行普通用户操作")
} else {
    // 其他角色操作
    print("执行其他角色操作")
}

如果大部分用户是管理员,将userRole == "admin"的判断放在最前面可以提高效率。

避免过度嵌套

过度嵌套的控制流语句会使代码可读性变差,并且可能影响性能。可以通过提取函数等方式来简化嵌套。

// 未优化的嵌套代码
let a = 5
let b = 3
if a > 0 {
    if b > 0 {
        if a > b {
            print("\(a)大于\(b)")
        }
    }
}
// 优化后的代码
func compare(_ a: Int, _ b: Int) {
    if a > 0 && b > 0 && a > b {
        print("\(a)大于\(b)")
    }
}
compare(a, b)

优化后的代码通过将嵌套逻辑提取到一个函数中,并合并条件判断,使代码更简洁且可能提高性能。

通过深入理解和合理运用Swift的各种控制流语句,开发者可以编写出逻辑清晰、高效的代码,无论是小型应用还是大型项目,控制流语句都是实现复杂功能的重要工具。在实际开发中,要根据具体需求选择合适的控制流,并注重性能优化和代码的可读性。