Swift中的"+" 与 "??"的优先级

前言

swift中, 我们要将几个String组合在一起是极其方便的,比如

第一种: 使用类似C++中的 "+" 运算符重载
let dog = "string1" + "_string2"
print(dog)

输出结果:
string1_string2
第二种: 使用Swift牛逼的插入法

又比如

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

输出结果:
string1_string2
第三种,使用Swift的 append(_ other: String) 函数

再比如

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

输出结果:
string1_string2

以上三种方式,都可以达到我们想要的效果。

但是,我们今天聊的并不是怎么拼接Swift中的字符串, 而是Swift中的另一种常见的类型:可选类型(Optional Type)

可选类型

Swift中,可选类型是十分常见的类型之一。我们都知道,当我们定义一个可选类型是,其默认值就是nil,如

var optionalVariable: String?

可选类型在Swift会使我们更为方便地处理一些特殊情况,比如值不存在,可以使我们的Swift代码更加安全,因为强制拆包一个未赋予任何值的可选类型,必然Crash!!!, 如

var dogVariable: String?
print(dogVariable!) // 奔溃,报错,因为强制拆包一个没有值的可选类型

但是在Swift中,这种奔溃在编码前期,可以给我们更好安全保障,因为我们可以通过一个可选值,去判断我们接收的服务端返回字段是否存在,或者在一个计算方法中是否合理使用所定义的可选值,在前期我们就可以检测到数据是否合理,变量定义是否冗余,书写是否规范等

当然,我相信几乎所有的程序猿都不会说喜欢自己写的代码奔溃,故此,Swift也不是说专门定义一个可选的概念给你,却没有解决的办法,办法还是有的,比如

var rabbit: String?
// 通过提供一个默认值来防止奔溃,rabbit的值不存在(即为nil),就输出默认值
print(rabbit ?? "defaultValue") 

// 输出结果
defaultValue

再比如,我们可以使用 if let绑定来安全并合理使用可选值

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

// 输出结果:
not exist!

我们还可以使用判断是否为nil来检查

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

输出结果:
eagle does not exist!

除此之外,我们也可以使用 guard let 语句,用法和 if let 类似,这里不赘述。

下面我们讲的是第一种方式,使用可选默认值结合Swift的字符串拼接符 "+", 来判断哪个的优先级更高!可能到这里,有人就说了,这么简单的问题谁不明白?还用得着小题大做写一篇博客,还啰嗦了这么多?很好,非常好的疑惑以及问题,那么下面,首先,请尝试做下面这道题目

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

好,第一次就做对上面这个题目的人,恭喜你,这篇文章你不需要继续看下去了。那么你的答案应该看下来是这个样子

default-swift
default-swift
default-swift

那么,错误的答案应该看起来是下面这个样子

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

剖析优先级 + 和 ??

从上面正确答案,其实我们已经可以看出 +优先级??优先级更高,因为,在for in的3次循环遍历中

表面上,

  • 第一次, value的值肯定不存在,为nil, 所以值应该是 default-swift

  • 第二次,value由于第一次已经赋值default-swift,所以理论上值应该变成 default-swift-swift

  • 第三次,value由于第二次已经赋值 default-swift-swift,所以理论上值应该变成 default-swift-swift-swift

实际上,由于优先级的原因( "+" > "??")

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

  • 第二次,由于第一次,value的值为default-swift,不再为 nil, 所以值存在,值还是第一次的值default-swift

  • 第三次,由于第二次,value的值还是default-swift,不再为 nil, 所以值还是存在,值还是第二次的值default-swift

综上,遍历循环三次,就算每次遍历都将值赋予value, 但是由于优先级的原因,打印的值永远是第一次的默认值,也就是 ?? 右边的 "default" + "-swift"

现在,回想一下你的答案,正确与否?

然后,我们来想一下,在项目中是否会总是不经意间犯这样低级的错误,那么如果这种情况下,我们想优先使用 ??的话,必须必须必须要加一个 括号(),如下

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

输出结果:
default-swift
default-swift-swift
default-swift-swift-swift

所以,在项目中,如果遇到类似的运算符交叉混合运算的情况下,务必要弄清楚优先级,当然,实在是不知道优先级的情况下,最最最安全的做法就是加上括号(),这样就确保万无一失了。

补充

事实上,+优先级也比三目运算符? :要高,比如

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

输出结果为:
default1
default2-swift
default2-swift
default2-swift
default2-swift

再看

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

输出结果
default1-swift
default2-swift
default2-swift
default2-swift
default2-swift

欢迎加入 iOS(swift)开发互助群:QQ群号:558179558, 相互讨论和学习!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342