簡(jiǎn)介
- 邏輯分支即常用的
if
仆救、switch
剃浇、三目這些通過(guò)邏輯判斷后決定后面執(zhí)行什么的邏輯語(yǔ)句俄占,通過(guò)分支語(yǔ)句可以控制程序的執(zhí)行方向和流程腔长。 - Swift 中邏輯分支的特點(diǎn)
- Swift 中沒(méi)有 C 語(yǔ)言中
非零即真
的概念; - 所有判斷條件必須顯式的指明具體的判斷條件
true
或者false
遏插。
- Swift 中沒(méi)有 C 語(yǔ)言中
if邏輯分支
-
簡(jiǎn)單體驗(yàn)
func demo() { let a = 10 if a >= 10 { print("OK") } }
以上代碼是一段正確的可執(zhí)行代碼捂贿,在執(zhí)行過(guò)程中程序會(huì)判斷 a 是否大于或者等于 10,如果滿(mǎn)足判斷條件就執(zhí)行
{}
里面的語(yǔ)句胳嘲,否則將不執(zhí)行厂僧。 -
Swift中 if 語(yǔ)句的特點(diǎn)
- 判斷語(yǔ)句不需要
()
; - 執(zhí)行語(yǔ)句必須要用
{}
了牛,即使后面只有一句代碼也不允許省略颜屠。
- 判斷語(yǔ)句不需要
-
可選項(xiàng)的邏輯判斷
-
在可選項(xiàng)的解包過(guò)程中如果我們使用
!
來(lái)強(qiáng)行解包,會(huì)出現(xiàn)可選值為空的風(fēng)險(xiǎn)白魂,例如以下代碼會(huì)出現(xiàn)的問(wèn)題:override func viewDidLoad() { super.viewDidLoad() demo(x: 10, y: nil) } func demo(x : Int?, y : Int?) { print(x! + y!) }
當(dāng)函數(shù) demo 中傳入一個(gè)
nil
值的時(shí)候會(huì)出現(xiàn)運(yùn)行錯(cuò)誤汽纤,這個(gè)錯(cuò)誤我們會(huì)經(jīng)常碰到,所以在選擇解包方法的時(shí)候就需要作出有效的判斷福荸,避免出現(xiàn)這種錯(cuò)誤蕴坪,以下代碼為修正版:override func viewDidLoad() { super.viewDidLoad() demo(x: 10, y: nil) } func demo(x : Int?, y : Int?) { if x != nil && y != nil { print(x! + y!) } else { print("x 或者 y 的值為 nil") } }
以上代碼解決了可選值為空的風(fēng)險(xiǎn),但是會(huì)造成新的問(wèn)題敬锐。如果可選值的賦值足夠復(fù)雜的情況下那么我們寫(xiě)出的代碼就會(huì)很丑陋背传,例如王巍在自己書(shū)中的一段反面教材:
復(fù)雜型可選項(xiàng)解包展示
從上面圖片中可以看出在解包一個(gè)復(fù)雜性json
字符串的時(shí)候出現(xiàn)了大量的if
語(yǔ)句和大量的花括號(hào),使代碼顯得冗余繁雜台夺,看了開(kāi)頭就不想看結(jié)尾的感覺(jué)径玖,這樣的代碼被人稱(chēng)為“不是給人讀的代碼”。在Swift中提供了一個(gè)簡(jiǎn)單的三目運(yùn)算符可以大大提高開(kāi)發(fā)效率也可以大大提高代碼的可讀性颤介,下面上代碼演示:override func viewDidLoad() { super.viewDidLoad() demo() } func demo(a : Int?, b : Int) { print((a ?? 0) + (b ?? 0)) }
上面代碼中使用一個(gè)
??
運(yùn)算符解決了代碼冗余的問(wèn)題梳星,而且可讀性也大大提高。這個(gè)??
是一個(gè)簡(jiǎn)單的三目滚朵,它的作用是判斷??
運(yùn)算符前面的可選值(如果有值使用值冤灾,如果沒(méi)有值使用運(yùn)算符后面的值作為替代運(yùn)算)。
值得注意的是辕近,??
運(yùn)算符的優(yōu)先級(jí)比較低韵吨,所以在使用的時(shí)候要注意優(yōu)先級(jí)。
-
if let / var 連用語(yǔ)法
if let
和 if var
連用不是單純的 if
語(yǔ)句移宅,是賦值的同時(shí)判斷對(duì)象是否為 nil
,判斷完之后{}
內(nèi)一定有值归粉,可以直接使用不需要解包。如果判斷對(duì)象為nil
漏峰,不執(zhí)行 {}
里的代碼直接向下執(zhí)行糠悼。以下代碼演示:
- if let
override func viewDidLoad() { super.viewDidLoad() demo() } func demo() { let memberName : String? = “張三” let memberAge : Int? = 18 if let oName = memberName, oAge = memberAge { print(oName + "今年" + String(oAge) + "歲了") } }
輸出到打印臺(tái)的結(jié)果:
if let 輸出結(jié)果 - if var
輸出到打印臺(tái)的結(jié)果:override func viewDidLoad() { super.viewDidLoad() demo() } func demo() { let memberName : String? = "張三" let memberAge : Ing? = 18 if var oName = memberName, let oAge = memberAge { oName = "李四" print(oName + "今年" + String(oAge) + "歲了") } }
let var 輸出結(jié)果
通過(guò)輸出結(jié)果可以看到,let var
的接收值在{}
中是允許修改的浅乔,這樣我們?cè)陂_(kāi)發(fā)中就可以靈活使用倔喂。
guard let 守護(hù)語(yǔ)句
Swift2.0的時(shí)候推出了guard let
守護(hù)語(yǔ)句,guard let
和 if let
的功能正好相反。如果被guard let
守護(hù)的對(duì)象值為 nil
就執(zhí)行 {}
里的代碼滴劲,如果對(duì)象值不為 nil
就繼續(xù)向下執(zhí)行攻晒。以下代碼演示:
override func viewDidLoad() {
super.viewDidLoad()
demo()
}
func demo() {
let memberName = "張三"
let memberAge = 18
guard let oName = memberName,
let oAge = memberAge else {
print("姓名或者年齡為nil")
return
}
// 代碼執(zhí)行到這,oName 和 oAge 一定有值
print(oName + "今年" + String(oAge) + "歲了")
}
打印臺(tái)輸出結(jié)果:
剛剛接觸
guard let
的朋友也許會(huì)覺(jué)得奇怪班挖,蘋(píng)果為什么會(huì)設(shè)計(jì)這樣一種奇葩的語(yǔ)法格式鲁捏。之前我接觸過(guò)的所有開(kāi)發(fā)語(yǔ)言中都沒(méi)有這樣的先例,剛學(xué)習(xí)Swift的時(shí)候我也覺(jué)得奇怪萧芙,但用熟練了之后發(fā)現(xiàn)這樣的設(shè)計(jì)方式真的很人性化给梅,并且能很有效的縮短閱讀代碼的時(shí)間。通常在做完判斷是否有值之后双揪,會(huì)做具體的邏輯判斷动羽,具體的邏輯通常代碼量會(huì)很大,如果用
if let
就會(huì)憑空多出一層分支渔期,guard let
可以有效的減少分支量运吓。
三目
- 簡(jiǎn)單體驗(yàn)
let a = 10 a > 5 ? print("變量a大于5") : print("變量a不大于5")
- Swift中三目的特點(diǎn)
- Swift中的三目運(yùn)算保持了和Objective-C一致的風(fēng)格;
- Swift中的三目運(yùn)算符支持空?qǐng)?zhí)行的操作疯趟,例如上面代碼中的
print("變量a不大于5")
永遠(yuǎn)不會(huì)被執(zhí)行到拘哨,這樣不會(huì)被執(zhí)行到的代碼可以省略為()
。
Switch邏輯分支
- Objective-C中的switch
- 在
Objective-C
中信峻,switch
的分支值類(lèi)型必須是整數(shù)倦青; - 每個(gè)語(yǔ)句都需要一句
break
; - 如果要穿透可以省略
break
; - 如果要定義局部變量,必須加
{}
確定該變量的作用域盹舞。
- 在
- Swift 中的 switch
-
Swift
中的switch
可以對(duì)任意的數(shù)據(jù)類(lèi)型進(jìn)行分支产镐,不再局限于整數(shù); - 一般情況下不需要
break
踢步; - 如果要多值穿透癣亚,使用
,
分隔; - 每一個(gè)
case
后面必須有可以執(zhí)行的語(yǔ)句贾虽,如果不需要做任何操作才需要使用break
逃糟; - 要保證處理所有可能的情況吼鱼,不然編譯器直接報(bào)錯(cuò)蓬豁,不處理的條件可以放在
default
分支中; - 每個(gè)分支中定義的臨時(shí)變量只在當(dāng)前
case
中有效菇肃,不需要再添加{}
地粪。
-
- 代碼示例
override func viewDidLoad() { super.viewDidLoad() doSwitch(score : "及格") } func doSwitch (score : String) { switch score { case: “及格”: let name = "員工" print(name + "成績(jī)60~79") case: "良": print("成績(jī)80~89") case: "優(yōu)": print("成績(jī)90~100") default: break } }
控制臺(tái)輸出結(jié)果:
switch演示控制臺(tái)輸出結(jié)果
修改值后輸出結(jié)果展示
總結(jié)
-
Swift
中不存在 C 語(yǔ)言中的非零即真
概念,在邏輯判斷的時(shí)候必須顯式的指明具體的true
或false
; -
??
運(yùn)算符可以用于判斷可選值是否為nil
琐谤,如果是nil
就是用后面的值替代蟆技; -
if let
和if var
的區(qū)別在于{}
里的值是否可以改變; -
guard let
與if let
語(yǔ)法相反,guard let
是Swift2.0
的時(shí)候推出的质礼; -
guard let
能夠一次性判斷每一個(gè)值旺聚,在真正的代碼邏輯部分少了一層嵌套,使代碼更加優(yōu)雅眶蕉; -
Swift
中的switch
不局限于整數(shù)砰粹,可以對(duì)任意的數(shù)據(jù)類(lèi)型進(jìn)行分支,寫(xiě)法基本與Objective-C
一致造挽。