Swift中的"+" 與 "??"的優(yōu)先級

前言

swift中, 我們要將幾個(gè)String組合在一起是極其方便的,比如

第一種: 使用類似C++中的 "+" 運(yùn)算符重載
let dog = "string1" + "_string2"
print(dog)

輸出結(jié)果:
string1_string2
第二種: 使用Swift牛逼的插入法

又比如

let string2 = "string2"
let cat = "string1_\(string2)"
print(cat)

輸出結(jié)果:
string1_string2
第三種所禀,使用Swift的 append(_ other: String) 函數(shù)

再比如

let string2 = "string2"
var string1 = "string1_"
string1.append(string2)
print(string1)

輸出結(jié)果:
string1_string2

以上三種方式稚机,都可以達(dá)到我們想要的效果伦仍。

但是,我們今天聊的并不是怎么拼接Swift中的字符串, 而是Swift中的另一種常見的類型:可選類型(Optional Type)怖喻。

可選類型

Swift中底哗,可選類型是十分常見的類型之一。我們都知道锚沸,當(dāng)我們定義一個(gè)可選類型是跋选,其默認(rèn)值就是nil,如

var optionalVariable: String?

可選類型在Swift會使我們更為方便地處理一些特殊情況,比如值不存在哗蜈,可以使我們的Swift代碼更加安全前标,因?yàn)閺?qiáng)制拆包一個(gè)未賦予任何值的可選類型坠韩,必然Crash!!!, 如

var dogVariable: String?
print(dogVariable!) // 奔潰炼列,報(bào)錯(cuò)只搁,因?yàn)閺?qiáng)制拆包一個(gè)沒有值的可選類型

但是在Swift中,這種奔潰在編碼前期俭尖,可以給我們更好安全保障氢惋,因?yàn)槲覀兛梢酝ㄟ^一個(gè)可選值,去判斷我們接收的服務(wù)端返回字段是否存在稽犁,或者在一個(gè)計(jì)算方法中是否合理使用所定義的可選值焰望,在前期我們就可以檢測到數(shù)據(jù)是否合理,變量定義是否冗余已亥,書寫是否規(guī)范等

當(dāng)然熊赖,我相信幾乎所有的程序猿都不會說喜歡自己寫的代碼奔潰,故此陷猫,Swift也不是說專門定義一個(gè)可選的概念給你秫舌,卻沒有解決的辦法,辦法還是有的绣檬,比如

var rabbit: String?
// 通過提供一個(gè)默認(rèn)值來防止奔潰足陨,rabbit的值不存在(即為nil),就輸出默認(rèn)值
print(rabbit ?? "defaultValue") 

// 輸出結(jié)果
defaultValue

再比如娇未,我們可以使用 if let綁定來安全并合理使用可選值

var elephant: String?
// 使用 if let 來安全檢查
if let value = elephant {
    print(value)
} else {
    print("not exist!")
}

// 輸出結(jié)果:
not exist墨缘!

我們還可以使用判斷是否為nil來檢查

var eagle: String?
if eagle == nil {
    print("eagle does not exist!")
}

輸出結(jié)果:
eagle does not exist!

除此之外,我們也可以使用 guard let 語句零抬,用法和 if let 類似镊讼,這里不贅述。

下面我們講的是第一種方式平夜,使用可選默認(rèn)值結(jié)合Swift的字符串拼接符 "+"蝶棋, 來判斷哪個(gè)的優(yōu)先級更高!可能到這里忽妒,有人就說了玩裙,這么簡單的問題誰不明白?還用得著小題大做寫一篇博客段直,還啰嗦了這么多吃溅?很好,非常好的疑惑以及問題鸯檬,那么下面决侈,首先,請嘗試做下面這道題目

var value: String?
for _ in 1...3 {
    value = value ?? "default" + "-swift"
    print(value!)
}

好喧务,第一次就做對上面這個(gè)題目的人赖歌,恭喜你枉圃,這篇文章你不需要繼續(xù)看下去了。那么你的答案應(yīng)該看下來是這個(gè)樣子

default-swift
default-swift
default-swift

那么俏站,錯(cuò)誤的答案應(yīng)該看起來是下面這個(gè)樣子

default-swift
default-swift-swift
default-swift-swift-swift

剖析優(yōu)先級 + 和 ??

從上面正確答案讯蒲,其實(shí)我們已經(jīng)可以看出 +優(yōu)先級??優(yōu)先級更高,因?yàn)橐拊?code>for in的3次循環(huán)遍歷中

表面上墨林,

  • 第一次, value的值肯定不存在犯祠,為nil旭等, 所以值應(yīng)該是 default-swift

  • 第二次,value由于第一次已經(jīng)賦值default-swift衡载,所以理論上值應(yīng)該變成 default-swift-swift

  • 第三次搔耕,value由于第二次已經(jīng)賦值 default-swift-swift,所以理論上值應(yīng)該變成 default-swift-swift-swift

實(shí)際上痰娱,由于優(yōu)先級的原因( "+" > "??")

  • 第一次弃榨,value = value ?? "default" + "-swift", 先算??右邊,所以value等于default-swift

  • 第二次梨睁,由于第一次鲸睛,value的值為default-swift,不再為 nil, 所以值存在,值還是第一次的值default-swift

  • 第三次坡贺,由于第二次官辈,value的值還是default-swift,不再為 nil, 所以值還是存在,值還是第二次的值default-swift

綜上遍坟,遍歷循環(huán)三次拳亿,就算每次遍歷都將值賦予value, 但是由于優(yōu)先級的原因,打印的值永遠(yuǎn)是第一次的默認(rèn)值愿伴,也就是 ?? 右邊的 "default" + "-swift"肺魁。

現(xiàn)在,回想一下你的答案隔节,正確與否万搔?

然后,我們來想一下官帘,在項(xiàng)目中是否會總是不經(jīng)意間犯這樣低級的錯(cuò)誤,那么如果這種情況下昧谊,我們想優(yōu)先使用 ??的話刽虹,必須必須必須要加一個(gè) 括號(),如下

var value: String?
for _ in 1...3 {
    value = (value ?? "default") + "-swift"
    print(value!)
}

輸出結(jié)果:
default-swift
default-swift-swift
default-swift-swift-swift

所以呢诬,在項(xiàng)目中涌哲,如果遇到類似的運(yùn)算符交叉混合運(yùn)算的情況下胖缤,務(wù)必要弄清楚優(yōu)先級,當(dāng)然阀圾,實(shí)在是不知道優(yōu)先級的情況下哪廓,最最最安全的做法就是加上括號(),這樣就確保萬無一失了初烘。

補(bǔ)充

事實(shí)上涡真,+優(yōu)先級也比三目運(yùn)算符? :要高,比如

var value: String?
for _ in 1...5 {
    value = value == nil ? "default1":"default2" + "-swift"
    print(value!)
}

輸出結(jié)果為:
default1
default2-swift
default2-swift
default2-swift
default2-swift

再看

var value: String?
for _ in 1...5 {
    value = (value == nil ? "default1":"default2") + "-swift"
    print(value!)
}

輸出結(jié)果
default1-swift
default2-swift
default2-swift
default2-swift
default2-swift

歡迎加入 iOS(swift)開發(fā)互助群:QQ群號:558179558肾筐, 相互討論和學(xué)習(xí)哆料!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吗铐,隨后出現(xiàn)的幾起案子东亦,更是在濱河造成了極大的恐慌,老刑警劉巖唬渗,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件典阵,死亡現(xiàn)場離奇詭異,居然都是意外死亡镊逝,警方通過查閱死者的電腦和手機(jī)壮啊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹋半,“玉大人他巨,你說我怎么就攤上這事〖踅” “怎么了染突?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長辈灼。 經(jīng)常有香客問我份企,道長,這世上最難降的妖魔是什么巡莹? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任司志,我火速辦了婚禮,結(jié)果婚禮上降宅,老公的妹妹穿的比我還像新娘骂远。我一直安慰自己,他們只是感情好腰根,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布激才。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瘸恼。 梳的紋絲不亂的頭發(fā)上劣挫,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機(jī)與錄音东帅,去河邊找鬼压固。 笑死,一個(gè)胖子當(dāng)著我的面吹牛靠闭,可吹牛的內(nèi)容都是我干的帐我。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼阎毅,長吁一口氣:“原來是場噩夢啊……” “哼焚刚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起扇调,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤矿咕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后狼钮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碳柱,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年熬芜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了莲镣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涎拉,死狀恐怖瑞侮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鼓拧,我是刑警寧澤半火,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站季俩,受9級特大地震影響钮糖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酌住,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一店归、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酪我,春花似錦消痛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谴古。三九已至,卻和暖如春稠歉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背汇陆。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工怒炸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人毡代。 一個(gè)月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓阅羹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親教寂。 傳聞我的和親對象是個(gè)殘疾皇子捏鱼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355