iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
0
Software Development

給我 30 天,給你一輩子:Swift 從零開始系列 第 12

Day 12 | Swift Loops 的糾葛:For-in 和 ForEach

  • 分享至 

  • xImage
  •  

Control Flow:Loops

Swift 提供了Loops 讓我們可以針對某個特定的程式碼,連續執行多次,並且是有順序性的,還記得在 Collection Types 使用了 for ... in loop 來走訪每個 Element,這是其中一個 Loop,除此之外,還可以使用 While、Repeat 以及 forEach,讓我們來看 For-in 以及 ForEach 到底是什麼。

Loops

Swift 有幾個常用的 Loops,這邊我想先來介紹一下這兩個 Loops:

  • for ... in
  • forEach

For-in Loop

在前面幾張已經簡單的提到過 for ... in 迴圈的使用方式,for 後面可以接一個臨時常數 ( 可以是 tuple ),會隨著 in 的範圍在每次回圈開始時,依序改變數值,而這個變數名稱你可以自行命名;in 後面接的是你想走訪的集合,可能是一個特定區間,也有可能是一整個元素,在 {} 內的就會是一個固定,且需要被連續執行多次的程式碼。

以之前的例子來看,你可以走訪某個陣列或是集合中的每個元素:

let 購物清單 = ["NX 200", "Pixel 5", "陶朱隱園"]
for 項目 in 購物清單 {
    print(項目)
}

/*
NX 200
Pixel 5
陶朱隱園
*/

你也可以使用 tuple 的方式來接收 Dictionary 中的 Key 以及 Value:

let 小胖便當價目表 = ["A餐": 100, "B餐": 200, "C餐": 150]
for (項目, 價格) in 小胖便當價目表 {
    print("\(項目) 的價格是 \(價格) 元")
}

/*
A餐 的價格是 100 元
B餐 的價格是 200 元
C餐 的價格是 150 元
*/

除此之外,剛剛還說到 in 後面可以是一個特定區間,你可以帶入 range 來表示:

for index in 1...3 {
    print("總共會執行三次,這是第 \(index) 次")
}

/*
總共會執行三次,這是第 1 次
總共會執行三次,這是第 2 次
總共會執行三次,這是第 3 次
*/

有一種情況是我只是想單純連續執行某段程式碼,但是無需使用到臨時變數,你可以使用 _ 來省略:

for _ in 1...3 {
    print("這裡會重複執行三次")
}

/*
這裡會重複執行三次
這裡會重複執行三次
這裡會重複執行三次
*/

ForEach

說到走訪每個元素,除了使用到 For-in 迴圈,還有另一種方法也可以走訪每個元素,那就是 forEach(_:)

forEach(_:) 是一個實體方法,是 Sequence Protocol 中的實體方法,只要實作這個協定的型別,都可以使用,舉凡 ArraysDictionariesSets 以及 Ranges 都有實作這個協定。

我們來拿 For-in 迴圈與他比較一下,也順便看一下他的使用方式:

let 購物清單 = ["NX 200", "Pixel 5", "陶朱隱園"]

// For-in Loop
for 項目 in 購物清單 {
    print(項目)
}

// ForEach Loop
購物清單.forEach { 項目 in
    print(項目)
}

這上面兩個 Print 出來的結果都是一樣的,forEach { element in ... },這是一個 Closures(閉包),在括弧中宣告一個獨立的常數來傳遞及使用,這部分後面章節會再詳細介紹。

但是這兩個真的沒有差別嗎?還是有的。

  1. 沒有辦法再 ForEach Loop 中使用 continue 或是 break 跳過當次的回圈或是跳出整個迴圈。
  2. 可以使用 return 的方式來跳過當次的迴圈,但無法跳出整個迴圈。

我們先來看 breakcontinue 的差別:

let 購物清單 = ["NX 200", "Pixel 5", "陶朱隱園"]
// break
for 項目 in 購物清單 {
    if 項目 == "Pixel 5" { break }
    print(項目)
}
// 如果項目是 Pixel 5 那就跳出整個迴圈
// 所以只會印出 NX 200

// continue
for 項目 in 購物清單 {
    if 項目 == "Pixel 5" { continue }
    print(項目)
}
// 如果項目是 Pixel 5 那就跳過當次迴圈
// 所以只會跳過 Pixel 5 印出 NX 200 跟 陶朱隱園

那既然了解了這兩個的差異,接著來看看 forEach 的限制:

let 購物清單 = ["NX 200", "Pixel 5", "陶朱隱園"]
購物清單.forEach { 項目 in
    if 項目 == "Pixel 5" { break }
    print(項目)
}

// 這裡會跳出一個錯誤訊息
// Unlabeled 'break' is only allowed inside a loop or switch, a labeled break is required to exit an if or do

如果要在 For-Each 中使用 break 或是 continue,在編譯的時候就會發生錯誤,跟你說不可以在裡面這樣加。

可以使用 return,來跳過當次迴圈,效果就有點像是 continue

let 購物清單 = ["NX 200", "Pixel 5", "陶朱隱園"]
購物清單.forEach { 項目 in
    if 項目 == "Pixel 5" { return }
    print(項目)
}

/*
NX 200
陶朱隱園
*/

這兩個確實很像,但是對於流程控制上,ForEach 的限制還是相對多一些,所以在使用上就需要特別注意囉! /images/emoticon/emoticon08.gif


上一篇
Day 11 | Swift Collection Types 番外篇: Hashable Protocol
下一篇
Day 13 | Swift Loops 的糾葛終章:While 和 Repeat-While
系列文
給我 30 天,給你一輩子:Swift 從零開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言