Swift 当使用循环时,建议你这么做 | 七日打卡

2,166 阅读5分钟

点赞评论,感觉有用的朋友可以关注笔者公众号 iOS 成长指北,持续更新

本文是 《Swift 100 Days》系列的的第 4 天, Swift 100 Days 是笔者记录自己 Swift 学习的记录,欢迎各位指正。

在实际编程过程中,循环是一个基本概念。你可以使用循环来时你的代码更具表达性、更加优雅。

Swift 中有多种循环语句,他们的底层机制是相同的。重复运行一些代码,直到条件语句不被满足。

For 循环

For 循环是最常见的循环语句。

在其他语言中,典型的 For 循环语法是使用这种格式 : for(i = 0; i < n; i++) { ... }。但 Swift 则不同,因为它的 for-in 语法可以用于遍历范围、集合、序列、迭代器甚至字符串。

数组,字典和集合之类的对象类型称为集合。

// 区间
for i in 0..<5 {
    print("\(i)")
}

//数组
let albums = ["Red", "1989", "Reputation"]

for album in albums {
    print("\(album) is on Apple Music")
}
// 使用enumerated()可以帮助数组去获取
for (index, album) in albums.enumerated() {
    print("\(index) = \(album)")
}

// 字典
let scores = ["Bob": 42, "Alice": 99, "Jane": 13]

for (name, score) in scores {
    print("\(name)'s score is \(score)")
}

...

在 Swift 中,我们可以使用下划线_ 来代替变量名,当你在{}中不需要使用这个变量时:

// 区间
for _ in 0..<5 {
    print("my name is iOS")
}

更加灵活的区间处理

有时候我们在使用区间是,我们需要有一定程度的跳跃区间,比如每隔 5 个加一次。

// 如果我们使用  `0..<60` 时,我们需要每隔 5 个加入结果数组中
// [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
var result = Array<Int>()

for num in 0..<60 {
    if num % 5 == 0 {
        result.append(num)
    }
}

result = []
//半开区间
for num in stride(from: 0, to: 60, by: 5) {
    result.append(num)
}

// 闭区间
result = []
for num in stride(from: 0, through: 55, by: 5) {
    result.append(num)
}

注意

在我们使用区间运算符的时候有一个有趣的现象

for num in 0...0 {
 print("0...0 = \(num)")
}

for num in 0..<0 {
 print("0..<0 = \(num)")
}

// 会打印 0...0 = 0

理解循环其实就是判断是否在某一个区间内,而闭区间其实是包含结果的。

(0...0).isEmpty // false  //从 0 开始,到 0 结束
(0..<0).isEmpty // true

所以在遍历数组时,我们更倾向于使用 0..<items.count 而不是0...items.count-1。前者更加易读且更加简洁

for i in 0..<items.count {
// Do stuff...
}

While 循环

第二种循环语句就是 While 循环。设定一个条件语句,可以是单一或者多个条件语句进行合并,当不符合条件时,跳出循环。

事实上 While 循环的最佳实践是当你不知道需要循环多少次的时候。While 循环的条件判断是在循环开始时计算的。

while(condition == true) {
    // Repeat this
}

例如,我们可以通过这个方式去遍历数组里面的值

let colors = ["Red", "Green", "Blue", "Orange", "Yellow"]
var colorCounter = 0
while colorCounter < 5 {
	print("\(colors[colorCounter]) is a popular color.")
	colorCounter += 1
}

事实上,我们一般直接使用 for...in 去遍历数组,我们期待我们的 While 循环语句可以让我们对条件更具操作性

var cats: Int = 0
while cats < 10 {
	cats += 1
	print("I'm getting another cat.")
	if cats == 4 {
		print("Enough cats!")
		cats = 10
	}
}

Repeat-While 循环

与 While 循环语句很类似,唯一不同的是repeat-while 循环,是每次在循环结束时计算条件是否符合。所以它是先执行一次循环语句,然后再去判断条件是否符合。

Swift 语言的 repeat-while 循环和其他语言中的 do-while 循环是类似的。

repeat {
    // Do this
} while(condition == true)

与 While 循环语句相比,使用repeat-while 循环会打印出This is false

while false {
    print("This is false")
}

repeat {
    print("This is false") 
} while false

repeat-while 是在每次循环结束的时候判断条件是否符合,所以它无论如何都会去调用一遍循环语句的主体部分。在实际项目过程中,当我们需要保证至少执行一次,但是又可能出现多种循环时,我们可以使用 repeat-while 循环。

控制转移语句

在实际编程环境中,我们并不需要走完整个循环,或者不需要到条件语句为false的时候才跳出循环语句。

比如,假设我们有一个考试成绩的数组,我们仅仅想知道有没有人得 100 分或是 0 分,此时我们就需要在找到分数为 0 或者 100 时,直接跳出循环:

let testScores = [100, 50, 80, 70, 40, 99, 88, 77]

let someOneIs100 = false

for score in testScores {
    if score == 100 {
        someOneIs100  = true
        break
    }
}

带标签的语句

前缀为(label: Statement)形式的语句称为带标签的语句。

label name: Statement

标签是一个标识符,可以稍后在 breakcontinue 语句中引用它。对于嵌套条件语句,以及嵌套循环来说有很多用处。当然也有助于你整理你的条件语句和嵌套循环。

let lable1 = 10
let lable2 = 20
let label3 = 30
let label4 = 40

firstIf: if lable1 > 5 {
    secondIf: if lable2 > 15 {
        thirdIf: if label3 > 25 {
            print(label4)
        }
    }
}

break

Swift 的 break 关键字可以让我们立即退出循环,不管我们讨论的是哪种循环。当在一个循环体中使用 break 时,会立刻中断该循环体的执行,然后跳转到表示循环体结束的大括号(})后的第一行代码。不会再有本次循环的代码被执行,也不会再有下次的循环产生。

退出嵌套循环

当我们在一个嵌套循环中进行遍历时,即一个循环体中有另一个循环体, 同时跳出当前循环和外部循环是很常见的。

在其他语言中,我们可能需要一个判断条件用作外部循环的判断条件。当内部循环满足条件时,判断外部循环是否也满足条件,然后在跳出外部循环。

for i in 1...10 {
    var needBreak = false
    for j in 1...10 {
        let product = i * j
        if product == 30 {
            needBreak = true
            break
        }
    }
    if needBreak {
        break
    }
}
// 使用标签语句标记外部循环
outerloop: for i in 1...10 {
    innerloop: for j in 1...10  {
        let product = i * j
        if product == 30 {
            break outerloop
        }
    }
}

在上面的程序中,有两个带标签的语句 outerloop: for...ininnerloop:for...in

标签名 outerloopinnerloop 可以与break 语句一起使用。

语句 break outerloop 终止两个循环并结束程序。标签名 innerloop 可以省略

continue

在一些情况下,我们需要跳过一些特定值的处理,或者是跳出当前处理语句。当程序到达 continue 语句时,它跳过循环体内的其他语句,并将再次检查条件语句。

for j in 1...2 {
    for i in 1...5 {
        if i == 4 {
            continue
        }
        print("i = \(i)")
    }
    print("j = \(j)")
}

//  不会打印 4
continue 语句中的标签

break 语句一样。我们同样可以使用标签语句来跳到嵌套循环或条件语句中的某一层。

outerloop: for j in 1...2 {
    innerloop: for i in 1...5 {
        if i == 4 {
            continue outerloop
        }
        print("i = \(i)")
    }
    print("j = \(j)")
}

在程序中,我们使用了语句 continue outerloop 来跳过内部循环和外部循环中的语句执行。在这个过程中,ij 的值都被更新到范围内的下一个数字。

continue 和 break

当我们使用 continue 时,我们说的是 我完成了这个循环的当前运行,Swift 将跳过循环体的其余部分,并转到循环中的下一项。但是,当我们说 break 时,我们是说 我已经完成了这个循环,所以完全退出。 这意味着Swift将跳过循环体的其余部分,但也会跳过循环余下的项。