Swift中的三元条件运算符:有什么用?

开发人员熟悉三元运算符(或更确切地说是三元条件运算符)。 它不是特定于Swift的,而是许多编程语言中的基本运算符。 如何在Swift中使用它? 对于许多开发人员来说,“是这样还是那样?”,只要代码仍然可以编译并完成工作,这只是喜好和习惯的问题。 对我来说,这是一个有趣的问题,值得寻找答案。

首先,这是Swift.org上Ternary运算符的定义:

三元条件运算符是具有三部分的特殊运算符,其形式为question ? answer1 : answer2 question ? answer1 : answer2 。 这是根据question是对还是错来评估两个表达式之一的捷径。 如果question为真,它将评估answer1并返回其值; 否则,它评估answer2并返回其值。

三元运算符通过减少1个缩进级别来帮助使代码变平,因此有助于嵌套if -s来解决著名的厄运金字塔

例如,此代码

 让持续时间:TimeIntervalif进度<0.2 { 
持续时间= 1.0
}其他{
持续时间= 2.0
}

可以通过使用此?:模式来以一种优雅的方式缩短

 让持续时间:TimeInterval =进度<0.2?  1.0:2.0 

整齐!

就个人而言,我喜欢在代码中使用此运算符。 每当需要分支时,我都想知道是否要使用三元运算符来实现。

但是,在某些情况下,我还是更喜欢 switch


情况#1:当代码可读性受到损害时

三元运算符通常使代码更紧凑,但不应将其链接或嵌套。 我同意这样做时可以减少代码行,但那样可能会伤到你的眼睛(和其他人)🙂

假设我有一个名为BatteryLevel的枚举:

 枚举BatteryLevel { 
大小写无效
小写
案例中
情况高
}

现在,我要在其中添加一个初始化程序init(percentage: Int) 。 我可以做这个:

 初始化(百分比:整数){ 
自我=(0 ... 20)〜=百分比? .low:((21 ... 50)〜=百分比?.medium:((51 ... 100)〜=百分比?.high:.invalid))
}

而且由于三元运算符是右关联的,因此我可以删除一些括号来实现:

 初始化(百分比:整数){ 
自我=(0 ... 20)〜=百分比? .low:(21 ... 50)〜=百分比? .medium:(51 ... 100)〜=百分比? .high:.invalid
}

代码变得不太混乱,但是我认为switch是更好的选择

 初始化(百分比:整数){ 
切换百分比{
情况0 ... 20:自我=。低
情况21 ... 50:自我=。中等
案例51 ... 100:自我=。高
默认值:self = .invalid
}
}

情况2: 当我判断未正确使用三元运算符时

最近,一位同事向我分配了请求请求,并要求我检查他的代码。 我停在这样的一行:

 应该扩展?  expand():塌陷() 

代码会编译。 有用。 没问题。 但是等等,有一个。

我记得在另一个项目中,团队负责人向我展示了类似的代码行,并问我是否可以找到“错误”的内容。 好吧,这是关于expand()collapse()的返回类型— Void 。 根据我当时的知识, Void方法不会返回任何值。 虽然三元运算符期望answer1answer2部分(请参见页面顶部的定义)返回值,但在我看来, Void不应该被视为适用。

这次,我的同事认为,在Swift中,Void实际上是一个空元组。

正如苹果所说的Void

typealias Void = ()

声明函数或方法时,如果不返回任何值,则无需指定返回类型。 但是,函数,方法或闭包的类型始终包含返回类型,如果未指定,则为Void

在声明不返回值的闭包,函数或方法时,请使用Void或空元组作为返回类型。

这仍然没有说服我。 例如,对于返回Int的方法,Int结果就是它的全部含义。 对于返回Void的方法(或空元组,或者没有有用的值),在返回之前进行的操作很重要。 2 Void总是相等的( answer1 == answer2给出true ),没有兴趣比较它们。 据我了解,根据其定义,三元运算符是2个值之间的选择,而不是2个副作用。

因此,我再次认为不要在Void上使用三元运算符。

如果是我,我会用if

 如果应该展开{ 
扩大()
}其他{
坍方()
}

如果Java / C#开发人员以这种方式使用三元运算符,则将获得编译时错误。 在Swift中,编译器接受表达式&不会引发此类错误。 Swift很简单,还是我很难? :))


情况3:在漂亮度/性能之间进行权衡时

有时我会看到有关执行时间以及不同方法/做事方式的复杂性的讨论,但是我并没有引起太多关注。 我总是在完成任务之前进行一些代码优化,但最终我知道这还不够。

我不久前读到的一篇关于构建时间的文章指出,使用三元运算符可能会导致更长的构建时间。

我尝试了对项目进行一些相同的更改,并发现它们确实缩短了构建时间(根据提供的工具)。 那是我开始更加关心代码性能的时候。

在准备这篇文章时,我运行了一个简单的代码,第一次尝试使用if ,第二次尝试使用三元运算符?: 。 以下是我得到的:

差异非常明显。

有时我们只需要if truefalse情况 三元运算符总是需要两者,其中之一可能是多余的,或多或少会影响性能。

即使我同时处理了if这两种情况它的运行速度也相当快。

好吧,有时很难同时兼顾性能,可读性和紧凑的代码。 这是你的选择。


我想在大多数情况下可以使用三元条件运算符代替if来帮助缩短代码,但是绝对不能代替if 。 在简单情况下,此运算符是一个不错的选择,而在其他情况下,请考虑以更经典的方式完成任务。


这些是我在三元条件运算符上的个人经验。 如果您发现我的帖子有帮助,请随时鼓掌;如果您认为我在任何时候都错了,请留下评论并指正我。 编码愉快!