7.3 條件語句

7.3 條件語句

我們總會遇到這樣的需求:

如果下雨就打雨傘,如果出太陽就打遮陽傘,其他情況不打傘

或者

成績在90分以上的學生獲得優(yōu)秀獎,在80分以上的獲得出色獎,在60以上的獲得努力獎,其他的被批評。

這就是條件,事情的發(fā)生很多都是有條件的。Swift 提供了兩種條件語句,ifswitchif適合簡單的情況,比如:

男生請左轉(zhuǎn),女生請右轉(zhuǎn)

switch 適合相對復雜的情況,比如上面根據(jù)分數(shù)評等級的例子。

If

if會執(zhí)行條件語句,如果是true則執(zhí)行一段代碼,否則跳過。如

var temperatureInCelsius = 16
if temperatureInCelsius <= 20 {
  println("It's a little cold. Consider wearing a scarf.")
}

這個例子判斷了當前的天氣,如果低于5攝氏度,就輸出這句溫馨的關(guān)懷。
當然可以更復雜一些:

var temperaturInCelsius = 24
if temperaturInCelsius <= 20 {
  println("It's a little cold. Consider wearing a scarf.")
} else {
  println("It's not that cold. Wear a t-shirt.")
}

這段代碼多了一個else分句,該分句就是我們平時說的,否則。這段代碼首先判斷了當前的溫度,如果低于20提示你要帶一條圍巾,否則穿一件t-shirt。
還可以更復雜一些:

var temperaturInCelsius = 32
if temperaturInCelsius <= 20 {
  println("It's a little cold. Consider wearing a scarf.")
} else if temperaturInCelsius >= 30 {
  println("It's really warm. Don't forget to wear sunscreen.")
} else {
  println("It's not that cold. Wear a t-shirt.")
}

可見我們可以連續(xù)使用ifelse ifelse,表達一個完整的意思。如果上面的一個ifelse if條件語句true那么就會進入該ifelse if的代碼區(qū)域執(zhí)行代碼,之后跳出整個if,而不會繼續(xù)執(zhí)行后面的 else if

如果男生就向左轉(zhuǎn),否則向右轉(zhuǎn):

var gender = "Male"
if gender == "Male" {
  println("Turn left")
} else {
  println("Turn right")
}

如果下雨就打雨傘,如果出太陽就打遮陽傘,其他情況不打傘

var weather = "sunny"
if weather == "sunny" {
  println("Take a bumbersoll with you")
} else if weather == "rainy" {
  println("Take an umbrella with you")
}

成績在90分以上的學生獲得優(yōu)秀獎,在80分以上的獲得出色獎,在60以上的獲得努力獎,其他的被批評。

var score = 100
if score >= 90 {
  println("Excellent")
  // 代碼執(zhí)行完這句話,不會繼續(xù)執(zhí)行下面的判斷,而是跳出整個if
} else if score >= 80 {
  println("Good")
} else if score >= 60 {
  println("OK)
} else {
  println("Work harder")
}

Switch

switch用于較復雜的情況。switch的標準格式如下:

switch VALUE_TO_TEST {
  case VALUE_1:
    ACTIONS_TO_VALUE_1
  case VALUE_2,
  VALUE_3:
    ACTIONS_TO_VALUE_2_OR_VALUE_3
  default:
    ACTIONS_IF_NOT_MATCHED
}

每個switch語句都是由多情況斷組成的,每個情況由關(guān)鍵字case開始,case后是進入這個情況的條件。除了由case開始的情況外,還有由default開始的,稱之為默認情況。每個情況都必須相應的代碼段,而不能為空。switch根據(jù)VALUE_TO_TEST的值,判斷該進入哪個情況執(zhí)行該情況,執(zhí)行相應的代碼。
每個switch語句都需要是完備的。就是說每一個VALUE_TO_TEST的可能值,都必須出現(xiàn)在一個情況中。如果由case引導的情況沒有成功匹配VALUE_TO_TEST的值,那么就會進入默認情況。如果由case引導的情況不是完備的,則必須包含默認情況。
下面的例子判斷了一個字母是否為元音:

let someCharacter: Character = "e"
switch someCaracter {
case "a", "e", "i", "o", "u":
  println("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
  println("\(someCharacter) is a consonant")
default:
  println("\(someCharacter) is not a vowel or a consonant")
}

不同情況間不會穿越

與 C 和 Objective-C 不同,Swift 的switch的情況不會穿越,除非顯式的指出我們需要穿越。
例如下面這段代碼,Swift 編譯器會報錯:

let anotherCharacter: Character = "a"
switch anotherCharacher {
case "a":
case "A":
  println("The letter A")
default:
  println("Not the letter A")
}

在 C 中,無論"a"或者"A"都會輸出"The letter A",并且還會繼續(xù)輸出"Not the letter A"; 但是在 Swift 中,編譯器會報錯。這種情況我們應該使用 Swift 提供的多值匹配:

let anotherCharacter: Character = "a"
switch anotherCharacher {
case "a", "A":
  println("The letter A")
default:
  println("Not the letter A")
}

后面章節(jié)會介紹關(guān)鍵字fallthrough,該關(guān)鍵字可以使Swift的情況穿越

范圍匹配

當我們判斷一個數(shù)字的范圍時,多值匹配變得力不從心。例如我們想根據(jù)銀河中的星星個數(shù)輸出一句文字描述其數(shù)字的范圍:

let count = 3_000_000_000_000
let countedThings = "stars in the Milky Way"
var naturalCount: String
switch count {
case 0:
    naturalCount = "no"
case 1...3:
    naturalCount = "a few"
case 4...9:
    naturalCount = "several"
case 10...99:
    naturalCount = "tens of"
case 100...999:
    naturalCount = "hundreds of"
case 1000...999_999:
    naturalCount = "thousands of"
default:
    naturalCount = "millions and millions of"
}
println("There are \(naturalCount) \(countedThings).")

元組匹配

Swift 的switch支持同時匹配多個值,使用元組將其組合起來,成為一個元組變量,傳入switch進行比較。比較兩個元組時,有時我們只想比較其中某個位置的值,此時我們可以用下劃線忽略不需要比較的位置。
這回我們用直角坐標系來舉個例子。我們在坐標系中繪制一個邊長為4的正方形,其四個定點分別在(2,2)、(2,-2)、(-2,-2)以及(-2,2)。然后我們判斷該坐標系中的一個點是處于原點、坐標軸上還是我們的方框內(nèi)。

let somePoint = (1, 1)
switch somePoint {
case (0, 0):
    println("(0, 0) is at the origin")
case (_, 0):
    println("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
    println("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
    println("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
    println("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}

somePoint同時滿足多個情況時,第一個滿足的情況會被執(zhí)行,而其他的都會被跳過。

值綁定

switch情況的條件語句可以進行值綁定,可以將值綁定到一個作用域為該情況代碼段的常量或變量上。
還是用直角坐標系舉例:

let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
    println("on the x-axis with an x value of \(x)")
case (0, let y):
    println("on the y-axis with a y value of \(y)")
case let (x, y):
    println("somewhere else at (\(x), \(y))")
}

switch語句判斷anotherPoint是否在坐標軸上,如果是輸出其非0的坐標。
該例中第一個情況綁定了anotherPoint的橫坐標,并將其縱坐標被限制為0,任何縱坐標為 0 的點都會進入這種情況,包含原點和其他 x 軸上的點。橫坐標被綁定在名為x的常量上;第二個情況綁定了縱坐標,并限制橫坐標為0,除了原點外,所有 y 軸上的點都被匹配到這個情況中;而其他的所有不在坐標軸上的點都進入了第三個情況,我們分別綁定了該點的橫縱坐標。
因為所有以case引導的情況已經(jīng)可以完備的表達點在直角坐標系的全部情況,所以不需要default了。

Where

switch的情況,除了可以進行值匹配以外還可以通過where子句進行附加條件判斷。
我們還用直角坐標系舉例,我們想判斷一個點是否在直角坐標系的對角線上。

let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
    println("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
    println("(\(x), \(y)) is on the line x == -y")
case let (x, y):
    println("(\(x), \(y)) is just some arbitrary point")
}

三種情況都進行了值綁定,綁定后我們又進行了進一步條件判斷。第一個情況中,我們判斷該點的橫縱坐標是否相同,這樣的點在一三象限的角平分線上;第二個情況中,我們判斷改點的橫縱坐標是否相反,這樣的點在二四象限的角平分線上;其余的情況通過不帶where子句的值綁定匹配。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,804評論 18 139
  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile麗語閱讀 3,853評論 0 6
  • 53.計算字符 在字符串中獲取字符值的數(shù)量, 可以使用字符串字符屬性中的計數(shù)屬性: let unusualMena...
    無灃閱讀 1,119評論 0 4
  • LDA(Latent Dirichlet Allocation)是一種文檔主題生成模型,也稱為一個三層貝葉斯概率模...
    chaaffff閱讀 1,919評論 0 2
  • 模式定義 定義一系列算法,將它們一個個封裝起來,并且使他們之間可以相互替換。本模式使得算法可以獨立于使用它的客戶而...
    FX_SKY閱讀 249評論 0 0