作者 | Aaron Dean,日期 | 2020 – 04 – 16

本文介绍 Swift 语言中常见的运算符(operators),基于Xcode 11.4 + Swift 5.2,所用示例代码均在 Xcode 11.4 中编译通过。文章内容如下:

  1. 算术运算符(Arithmetic Operators)
  2. 赋值运算符(Assignment Operator)
  3. 比较运算符(Comparison Operators)
  4. 三元条件运算符(Ternary Conditional Operator)
  5. 空合运算符(Nil-Coalescing Operator)
  6. 区间运算符(Range Operators)
  7. 逻辑运算符(Logic Operators)

如果你需要获取更多/更新信息,请查看苹果开发者文档(英文),GitHub 上也有该文档的中文版,但不能保证是最新的。

 


Swift语言支持大多数标准 C 运算符,并改进了一些功能以消除常见的编码错误。

运算符包括一元(unary)、二元(binary)、三元(ternary)运算符。“元”即该运算符所需的操作数(operands)个数。

  • 一元运算符:只需一个操作数,既可作为前缀出现(如-a、!b等),也可作为后缀出现(如可选类型中使用的?和!:c?、d!)。
  • 二元运算符:需要两个数,作为中缀出现,如 3 + 4 中的“+”。
  • 三元运算符:和 C 语言一样,Swift 有且仅有一个三元运算符——条件运算符(a ? b : c)。

下文将对 Swift语言中使用的基本运算符逐一进行介绍。

1. 算术运算符

四则运算(four fundamental rules)

Swift 支持对所有的数字类型进行加、减、乘、除(+、-、*、/)四种标准的算术运算符。另外,运算符“+”也可以用于连接字符串。不同于 C 语言和 Objective-C中的算术运算符,默认情况下Swift 的算术运算符不允许值溢出,以避免存储越界时出现意外结果。示例代码:

取余(Remainder Operator)

取余运算符 (a % b) 即用于求取余数( remainder)的运算符,运算符“%”在其他语言中也叫“模”。但是严格来说,在 Swift 对负数使用运算符“%”是求余数而不是“模”。另外,“ a % b”与“ a % -b”结果相同,即取余运算会将 b 的符号忽略。

一元加/减(Unary Plus/Minus Operator)

即通常所说的“正负号”,用来标识一个数的正负。“一元减”即取相反数,在一个数前面写上负号“-”,表示取这个数的相反数。“一元加”即通常所说的“正号”,在一个数前面加上“+”没有任何改变。

2. 赋值运算符

赋值运算符

赋值运算符的作用是:初始化以及给变量重新赋值。如果赋值运算符(=)的右边是一个包含多个数值的元组( tuple),则可以一次将其元素分解为多个常量或变量。与C和Objective-C中的赋值运算符不同,Swift中的赋值运算符本身并不返回值。Swift 这样做是为了避免开发者误将赋值运算符用作恒等运算符(==)。示例如下:

复合赋值运算符(Compound Assignment Operators)

和 C 语言一样,Swift 也将赋值运算符(=)与其他运算符组合使用,构成复合运算符。如“+=”示例如下,等价于“a = a+2”,即先将a与 2 相加,再把所得结果赋给 a。类似的还有“-=”、“=”、“/=”、“%=”

3. 比较运算符

Swift支持所有标准 C 的比较运算符,每个比较运算符都返回一个布尔(Bool)值,表示语句的真假。比较运算符通常用在条件语句中(如 if 语句)。具体包括:等于(a == b)、不等于(a != b)、大于(a > b)、大于等于(a >= b)、 小于(a < b)、小于等于(a <= b)。示例如下:

用在 if 语句的条件判断部分:

两个元组(tuples)也可以进行比较,前提是它们的类型和值的数目相同,且类型应是可比较的,比如不能拿布尔类型的值来比较。比较规则:从左往右,一次比较一个值,直到找到不等的值为止,否则这两个元组相等。需要说明的是,Swift 标准库包含了元素少于 7 个的元组比较运算符,如果要比较大于等于 7 个元素的两个元组,需要自己实现比较运算符。示例如下:

Swift也提供了两个标识运算符(=== 和 !==),可以使用他们来测试两个对象引用是否都引用了同一对象实例。关于此内容将在类(class)的部分详细介绍。

4. 三元条件运算符

question ? answer1 : answer2被称为三元条件运算符(Ternary Conditional Operator),是下列if-else 语句的简写形式。需要注意的是,过度使用三元条件运算符可能会导致代码的可读性下降。因此,需要在代码的简洁性和易读性之间做出平衡,避免将三元条件运算符的多个实例组合到一个复合语句中。下面的 if-else 语句可以用更简短的三元条件运算符替代:

5. 空合运算符

空合运算符 (a ?? b) :表达式 a 总是可选类型,而表达式 b 的类型必须与a所存储的类型匹配。当a有值时,运算符“??” 会将其解包,若a没有值(即 a的值为 nil ),则该运算符会返回一个预先指定的默认值。这也称为“短路评估”( short-circuit evaluation)。nil-coalescing 运算符 (a ?? b) 是下面这句代码的简写:

如果 a 不等于 nil,就将 a 的值解析出来当做整个表达式的值返回,否则就将b 的值(默认值)当做整个表达式的值返回。

比如,变量 b 被定义为可选的String 类型,默认值是 nil。因为 b是一个可选类型,用户定义的颜色名b 没有值(即nil),表达式 b ?? a 的值就是a 的值”red”,并被赋给变量c。而当给可选类型的 b 赋值“blue”后,表达式 b ?? a 的值就是b的值”blue” ,并被赋给c。

6. 区间运算符

Swift 提供了 C 所没有的区间运算符,如闭区间运算符( a…b )、半开区间运算符( a..<b )、单侧区间运算符( a… 或 …b ),以便于简洁地表示值的区间范围。半开区间运算符(a..<b)在从 0 开始的数据结构中特别有用,比如数组(array)。示例代码如下:

单侧区间运算符不局限于在下标(subscripts)中使用,也可用在其他地方。需要说明的是,你可以在忽略其终值的单侧区间进行迭代,但不能在忽略第一个值的单侧区间进行迭代,因为忽略了起始值的单侧区间无法明确从哪里开始迭代。无论如何,都建议为循环添加明确的起始和结束条件。像数组这一类数据结构,当使用单侧区间时,已经隐含了“从 0 开始”和“到数组最后一个元素结束”的含义。另外,你也可以检查单边范围是否包含特定值。示例如下:

7. 逻辑运算符

逻辑运算符修改或组合布尔逻辑值真(true) 和 假 (false)。 Swift支持基于C语言的三种标准逻辑运算符:&&、||、!。

  • 逻辑与(a && b): a 和 b 必须同时为真,才能使整个表达式为真。当 a 为假时,不用求 b 的值就能得出整个表达式的值为假 。这也叫“短路评估”。
  • 逻辑或(a || b): a 和 b 只要有一个为真,整个表达式就为真。当 a 为真时,不用求 b 的值就能得出整个表达式的值为真。
  • 逻辑非( !a):当 a 为真时,!a 为假。当 a 为假 时,!a 为 为真。

组合逻辑运算符(Combining Logical Operators):你可以组合多个逻辑运算符来创建更长的复合表达式,如下面的门禁访问示例所示。这里需要注意的是,Swift逻辑运算符&&和|| 是左关联的,意味着具有多个逻辑运算符的复合表达式首先评估最左边的子表达式。

圆括号(Parentheses):有时在不需要圆括号时使用圆括号,可以使复杂表达式更易读。 如下面的门禁访问示例中,在复合表达式的第一部分周围添加圆括号,可以增加代码的可读性。

本文在简书鱼乐自学(网站)、微信公众号(扫描二维码关注)同步更新,欢迎访问。如果本文对你有用,欢迎收藏、赞赏并转发分享,转载或其他用途等请遵循CC BY 4.0协议


参考资料苹果开发者文档(英文)-基本运算符

文档协议知识共享署名 4.0国际 (CC BY 4.0)(共享 – 演绎 – 署名 – 不得附加限制)