IOS迷你教程3-Swift語言之流程控制(swift4.2)

告訴計算機在什么時候該做什么萨惑,稱做控制流捐康。

在本教程中,您將學(xué)習(xí)如何來控制流程庸蔼,從而讓計算機聽你的話解总。您還將了解布爾truefalse,以及如何使用它們來比較數(shù)據(jù)姐仅。

入門

此前學(xué)過了一些類型如Int花枫,DoubleString。在這里掏膏,您將學(xué)習(xí)另一種類型:布爾劳翰。

如,查找兩個數(shù)字中的較大者馒疹,答案是truefalse佳簸。

let yes = true // 類型推斷為Bool
let no = false // 類型推斷為Bool

布爾類型的值只能是truefalse

布爾運算符

布爾值通常用于比較值颖变。例如溺蕉,您可能有兩個值,并且您想知道它們是否相等:值是相同的(true)還是它們是不同的(false)悼做。

在Swift中疯特,使用==執(zhí)行此操作

let doesOneEqualTwo = (1 == 2)

swift推斷doesOneEqualTwo是一個Bool。顯然肛走,1不等于2漓雅,因此doesOneEqualTwo將是false

同樣朽色,你可以看看兩個值是否相等:

let doesOneNotEqualTwo = (1 != 2)

因為1不等于2邻吞,所以doesOneNotEqualTwo會是true

!取反操作葫男。

大于(>)抱冷,小于(<):

let isOneGreaterThanTwo = (1 > 2)
let isOneLessThanTwo = (1 < 2)

isOneGreaterThanTwofalseisOneLessThanTwotrue梢褐。

另外還有小于等于和大于等于:<=旺遮,>=赵讯,同理。

布爾邏輯

&&耿眉。如果兩個都是true边翼,結(jié)果才是true。否則鸣剪,結(jié)果是false组底。

let and = true && true

在這種情況下,and將是true筐骇。如果右邊的任何一個值是false债鸡,那么and就是false

||铛纬。只要其中一個為true厌均,則結(jié)果為true。

let or = true || false

在這種情況下饺鹃,or將是true。如果右邊的兩個值都是false间雀,那么or就是false悔详。如果兩者都是true,那么or仍然是true惹挟。

在Swift中茄螃,布爾邏輯通常應(yīng)用于多個條件:

let andTrue = 1 < 2 && 4 > 3
let andFalse = 1 < 2 && 3 > 4

let orTrue = 1 < 2 || 3 > 4
let orFalse = 1 == 2 || 3 == 4

也可以這樣:

let andOr = (1 < 2 && 3 > 4) || 1 < 4

字符串比較

在Swift,用于比較數(shù)字是否相等的==號也可以用來比較字符串:

let guess = "dog"
let dogEqualsCat = guess == "cat"

得出dogEqualsCat是一個布爾類型连锯,為false归苍。

與數(shù)字一樣,您不僅可以比較是否相等运怖,還可以比較一個值是否大于或小于另一個值:

let order = "cat" < "dog"

這時是按英文字母順序比較拼弃,ordertrue

if語句

流程控制的第一個也是最常見的是if,只有當(dāng)某個條件為true時才執(zhí)行:

if 2 > 1 {
  print("Yes, 2 is greater than 1.")
}

這是一個簡單的if語句摇展。如果條件是true吻氧,則將執(zhí)行大括號之間的代碼。如果條件為false咏连,則語句將不執(zhí)行大括號之間的代碼盯孙。

您可以擴展if語句:

let animal = "Fox"
if animal == "Cat" || animal == "Dog" {
  print("Animal is a house pet.")
} else {
  print("Animal is not a house pet.")
}

這里,如果animal等于"Cat"或者"Dog"祟滴,那么語句將運行第一個代碼塊振惰。如果animal不等于"Cat"或者"Dog",則將在else內(nèi)運行垄懂,以下內(nèi)容被打印到控制臺:

Animal is not a house pet.

else if

let hourOfDay = 12
var timeOfDay = ""

if hourOfDay < 6 {
  timeOfDay = "Early morning"
} else if hourOfDay < 12 {
  timeOfDay = "Morning"
} else if hourOfDay < 17 {
  timeOfDay = "Afternoon"
} else if hourOfDay < 20 {
  timeOfDay = "Evening"
} else if hourOfDay < 24 {
  timeOfDay = "Late evening"
} else {
  timeOfDay = "INVALID HOUR!"
}
print(timeOfDay)

if語句將逐個測試多個條件骑晶,直到true痛垛。無論后面的else-if條件是否為true,僅執(zhí)行第一條true后面的代碼透罢。

末尾的else子句來處理以上都為false的情況榜晦。

控制臺將打印出以下內(nèi)容:

Afternoon

封裝變量

if語句引入了一個新的概念范圍,這是一種通過使用大括號封裝變量的方法羽圃。

如乾胶,某地兼職工資的規(guī)定為:在40小時之前每小時25美元,之后每小時50美元朽寞。

通過以下方式計算您的工資:

var hoursWorked = 45

var price = 0
if hoursWorked > 40 {
  let hoursOver40 = hoursWorked - 40
  price += hoursOver40 * 50
  hoursWorked -= hoursOver40
}
price += hoursWorked * 25

print(price)

結(jié)果如下:

1250

hoursOver40是在if語句中聲明的新常量识窿。如果這樣會發(fā)生什么?

// ...

print(price)
print(hoursOver40)

這將導(dǎo)致以下錯誤:

Use of unresolved identifier 'hoursOver40'

此錯誤通知您脑融,您只能在創(chuàng)建它的范圍內(nèi)使用hoursOver40常量喻频。在這種情況下,if語句創(chuàng)建了一個新范圍肘迎,因此當(dāng)該范圍結(jié)束后甥温,您將無法使用該常量。

但是妓布,每個范圍都可以使用其父范圍中的變量和常量姻蚓。在上面的示例中,if語句內(nèi)部仍然可以使用您在父范圍中創(chuàng)建的pricehoursWorked變量匣沼。

三元運算

三元運算符即返回兩個值中的一個狰挡,這取決于條件是true還是false

(<CONDITION>) ? <TRUE VALUE> : <FALSE VALUE>

這是一個找出兩個變量中最小值的示例:

let a = 5
let b = 10

let min: Int
if a < b {
  min = a
} else {
  min = b
}

感謝三元運算符,您可以重寫為簡潔的代碼:

let a = 5
let b = 10

let min = a < b ? a : b

如果a < btrue释涛,則min的值為a;如果是false加叁,minb

注意:如果過度使用唇撬,可能會犧牲代碼的易讀性它匕。

循環(huán)

循環(huán)是多次執(zhí)行代碼的一種方式。在本節(jié)中窖认,您將了解while循環(huán)超凳。

循環(huán)時

當(dāng)while后面條件為true時,將循環(huán)執(zhí)行大括號中的代碼:

while <CONDITION> {
  <LOOP CODE>
}

每一次循環(huán)耀态,都會先檢查條件轮傍。如果條件是true,則執(zhí)行并準(zhǔn)備下一次循環(huán)首装。一旦條件為false创夜,則循環(huán)停止。就像if語句一樣仙逻,while循環(huán)也引入了一個范圍(大括號中的代碼)驰吓。

最簡單的while循環(huán):

while true {
}

這是一個永遠(yuǎn)不會結(jié)束的while循環(huán)(死循環(huán))涧尿,因為條件總是true。一個死循環(huán)可能不會讓程序崩潰檬贰,但很可能會讓計算機死機姑廉。

一個while循環(huán)示例:

var sum = 1

while sum < 1000 {
  sum = sum + (sum + 1)
}

此代碼計算一個數(shù)學(xué)序列,直到sum值大于1000翁涤。

循環(huán)執(zhí)行如下:

在第九次迭代(循環(huán))之后铁蹈,sum1023千元,循環(huán)條件sum < 1000變?yōu)?code>false,循環(huán)停止。

repeat-while循環(huán)

它與while循環(huán)的不同之處在于习蓬,在循環(huán)結(jié)束時判斷條件是否為true

repeat {
  <LOOP CODE>
} while <CONDITION>

這是上一節(jié)的示例级零,使用repeat-while循環(huán):

sum = 1

repeat {
  sum = sum + (sum + 1)
} while sum < 1000

在此示例中富纸,結(jié)果和之前相同集畅。但并非所有的時候都是一樣的。

while循環(huán):

sum = 1
while sum < 1 {
  sum = sum + (sum + 1)
}

repeat-while循環(huán):

sum = 1
repeat {
    sum = sum + (sum + 1)
}while sum < 1

while循環(huán)中届谈,條件從一開始就是false枯夜。說明不會執(zhí)行循環(huán)體,sum最終為1艰山。

repeat-while中湖雹,sum3,因為循環(huán)體將先執(zhí)行一次程剥。

跳出循環(huán)

有時你想早點結(jié)束循環(huán)劝枣√捞ぃ可以使用break語句织鲸,該語句會立即停止循環(huán)并繼續(xù)循環(huán)后面的代碼:

sum = 1

while true {
  sum = sum + (sum + 1)
  if sum >= 1000 {
    break
  }
}

條件為true,所以會永遠(yuǎn)循環(huán)溪胶。但一旦sum大于或等于1000搂擦,循環(huán)將結(jié)束。

高級控制流

在本節(jié)中哗脖,您將繼續(xù)學(xué)習(xí)如何控制代碼執(zhí)行瀑踢。您將了解另一個稱為for循環(huán)的循環(huán)。

范圍

在深入了解for循環(huán)語句之前才避,您需要了解一下ClosedRangeRange類型橱夭,它們可以表示一系列的數(shù)字。

封閉的范圍:

let closedRange = 0...5

三個點(...)表示范圍是從0到5(包括0和5)桑逝。即0, 1, 2, 3, 4, 5棘劣。

半開放范圍:

let halfOpenRange = 0..<5

范圍是從0到5,包括0但包括5楞遏。即0, 1, 2, 3, 4茬暇。

注意:
第二個數(shù)字必須始終大于或等于第一個數(shù)字首昔。
范圍通常用于for循環(huán)和switch語句中!

for循環(huán)

for <CONSTANT> in <RANGE> {
  <LOOP CODE>
}

循環(huán)以for關(guān)鍵字開頭糙俗,后面跟一個想在循環(huán)中使用的常量名勒奇,in后面為循環(huán)的范圍:

let count = 10
var sum = 0

for i in 1...count {
  sum += i
}

i的初始值為1,也就是范圍(1...count)的第一個數(shù)巧骚,每次循環(huán)之后都加1赊颠,直到等于count為止。

以下是每次迭代的isum的值:

i循環(huán)外部不可用网缝。

當(dāng)你在循環(huán)中不需要使用i時巨税,可以用下劃線:

sum = 1
var lastSum = 0

for _ in 0..<count {
  let temp = sum
  sum = sum + lastSum
  lastSum = temp
}

只是單純的想讓代碼執(zhí)行一定的次數(shù),不需要用到循環(huán)常量(上述i)粉臊。
0..<count半開草添,表示代碼將執(zhí)行count次,這是一種需要執(zhí)行多少次的常用方法扼仲。

也可以僅在某些條件下執(zhí)行循環(huán)远寸。如,想要計算總和但僅針對奇數(shù):

var sum = 0
for i in 1...count where i % 2 == 1 {
  sum += i
}

wherefor循環(huán)中的一個子句屠凶。循環(huán)只會在where條件為true時執(zhí)行循環(huán)體驰后。

continue聲明

有時你想跳過特定情況的循環(huán)迭代,而不想完全跳出循環(huán)矗愧≡钪ィ可以使用continue語句,該語句立即結(jié)束循環(huán)的當(dāng)前迭代并開始下一次迭代唉韭。

8?8乘法表:

full_board

假設(shè)您想要計算所有單元格的總和但排除所有偶數(shù)行:

first_board_example

使用for循環(huán):

sum = 0

for row in 0..<8 {
  if row % 2 == 0 {
    continue
  }

  for column in 0..<8 {
    sum += row * column
  }
}

模2為0時夜涕,該行是偶數(shù)行。在這種情況下属愤,continue跳出本次for循環(huán)女器,執(zhí)行下一次循環(huán)。

break一樣住诸,continue也適用于for循環(huán)和while循環(huán)驾胆。

switch語句

控制流的另一種是switch語句,它允許您根據(jù)變量或常量的值執(zhí)行不同的代碼贱呐。

一個非常簡單的switch語句:

let number = 10

switch number {
case 0:
  print("Zero")
default:
  print("Non-zero")
}

將輸出:

Non-zero

case后面的值(本例中為0)表示:當(dāng)number為此值時丧诺,執(zhí)行冒號后面的語句。default表示以上全沒有匹配到的話執(zhí)行下面的代碼奄薇。

另一個例子:

switch number {
case 10:
  print("It's ten!")
default:
  break
}

這次匹配到10驳阎,將執(zhí)行case下面的代碼。
break表示什么都不執(zhí)行,

switch語句適用于任何數(shù)據(jù)類型搞隐!以下是切換字符串的示例:

let string = "Dog"

switch string {
case "Cat", "Dog":
  print("Animal is a house pet.")
default:
  print("Animal is not a house pet.")
}

這將打印以下內(nèi)容:

Animal is a house pet.

case后接兩個值驹愚,這說明如果等于"Cat"或者"Dog"將執(zhí)行。

高級switch語句

case后接多種情況:

let hourOfDay = 12
var timeOfDay = ""

switch hourOfDay {
case 0, 1, 2, 3, 4, 5:
  timeOfDay = "Early morning"
case 6, 7, 8, 9, 10, 11:
  timeOfDay = "Morning"
case 12, 13, 14, 15, 16:
  timeOfDay = "Afternoon"
case 17, 18, 19:
  timeOfDay = "Evening"
case 20, 21, 22, 23:
  timeOfDay = "Late evening"
default:
  timeOfDay = "INVALID HOUR!"
}

print(timeOfDay)

將輸出以下內(nèi)容:
Afternoon

可以使用范圍讓代碼更簡潔:

var timeOfDay2 = ""

switch hourOfDay {
case 0...5:
  timeOfDay2 = "Early morning"
case 6...11:
  timeOfDay2 = "Morning"
case 12...16:
  timeOfDay2 = "Afternoon"
case 17...19:
  timeOfDay2 = "Evening"
case 20..<24:
  timeOfDay2 = "Late evening"
default:
  timeOfDay2 = "INVALID HOUR!"
}

print(timeOfDay2)

也可以像for循環(huán)一樣使用where子句(先聲明一個常量以便where子句中使用):

switch number {
case let x where x % 2 == 0:
  print("Even")
default:
  print("Odd")
}

這將打印以下內(nèi)容:

Even

如for循環(huán)一樣劣纲,聲明的常量在下面的代碼中不需要使用的話逢捺,可以用下劃線代替:

switch number {
case _ where number % 2 == 0:
  print("Even")
default:
  print("Odd")
}

部分匹配

let coordinates = (x: 3, y: 2, z: 5)

switch coordinates {
case (0, 0, 0): // 1
  print("Origin")
case (_, 0, 0): // 2
  print("On the x-axis.")
case (0, _, 0): // 3
  print("On the y-axis.")
case (0, 0, _): // 4
  print("On the z-axis.")
default:        // 5
  print("Somewhere in space")
}

switch語句使用部分匹配

  1. 精確匹配(0, 0, 0)。說明時3D空間的原點癞季。
  2. 匹配y = 0劫瞳,z = 0和x可為任何值。說明坐標(biāo)位于x軸上绷柒。
  3. 匹配x = 0志于,z = 0和y可為任何值。說明坐標(biāo)位于y軸上废睦。
  4. 匹配x = 0伺绽,y = 0和z可為任何值。說明坐標(biāo)位于z軸上嗜湃。
  5. 匹配其余坐標(biāo)奈应。

把上例中的下劃線聲明為變量,這樣可以在case后面的語句中使用:

switch coordinates {
case (0, 0, 0):
  print("Origin")
case (let x, 0, 0):
  print("On the x-axis at x = \(x)")
case (0, let y, 0):
  print("On the y-axis at y = \(y)")
case (0, 0, let z):
  print("On the z-axis at z = \(z)")
case let (x, y, z):
  print("Somewhere in space at x = \(x), y = \(y), z = \(z)")
}

使用let語法來提取相關(guān)值购披。然后使用字符串插值打印出來杖挣。

switch語句中沒有default選項。因為已經(jīng)窮舉了所有情況刚陡,所以不用寫默認(rèn)值惩妇。

注:想提取元組的所有值時,let (x, y, z)(let x, let y, let z)一樣筐乳。

最后歌殃,可以使用let-where語法來匹配更復(fù)雜的情況:

switch coordinates {
case let (x, y, _) where y == x:
  print("Along the y = x line.")
case let (x, y, _) where y == x * x:
  print("Along the y = x^2 line.")
default:
  break
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市哥童,隨后出現(xiàn)的幾起案子挺份,更是在濱河造成了極大的恐慌褒翰,老刑警劉巖贮懈,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異优训,居然都是意外死亡朵你,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門揣非,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抡医,“玉大人,你說我怎么就攤上這事〖缮担” “怎么了大脉?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長水孩。 經(jīng)常有香客問我镰矿,道長,這世上最難降的妖魔是什么俘种? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任秤标,我火速辦了婚禮,結(jié)果婚禮上宙刘,老公的妹妹穿的比我還像新娘苍姜。我一直安慰自己,他們只是感情好悬包,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布衙猪。 她就那樣靜靜地躺著,像睡著了一般布近。 火紅的嫁衣襯著肌膚如雪屈嗤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天吊输,我揣著相機與錄音饶号,去河邊找鬼。 笑死季蚂,一個胖子當(dāng)著我的面吹牛茫船,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扭屁,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼算谈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了料滥?” 一聲冷哼從身側(cè)響起然眼,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎葵腹,沒想到半個月后高每,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡践宴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年鲸匿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阻肩。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡带欢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乔煞,我是刑警寧澤吁朦,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站渡贾,受9級特大地震影響喇完,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜剥啤,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一锦溪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧府怯,春花似錦刻诊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至冲簿,卻和暖如春粟判,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背峦剔。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工档礁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吝沫。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓呻澜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惨险。 傳聞我的和親對象是個殘疾皇子羹幸,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)辫愉,斷路器栅受,智...
    卡卡羅2017閱讀 134,693評論 18 139
  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,151評論 0 13
  • 首先我想跟大家分享一個真實的事件:有一天太太回到家恭朗,看到先生躺在沙發(fā)上看電視屏镊,沒有煮飯,于是說:“你這個懶鬼...
    NLPer彭慧閱讀 441評論 0 1
  • 那天冀墨,當(dāng)西北風(fēng)把空氣中看似霧霾的霧水都吹散后闸衫,香蕉怪獸的真身就展現(xiàn)在眾人的眼前涛贯。每個路過的甲乙丙丁戊己庚辛诽嘉,疑惑地...
    我叫兩文錢閱讀 549評論 0 0
  • 早晚有一天要把自己整死,我想過得更好,活的更好虫腋,我的那些同學(xué)們骄酗,那些高中同學(xué)們,都活的好有朝氣悦冀,我也要那樣蓬勃
    辣椒小柒閱讀 201評論 0 0