高级运算符
1.0 翻译:xielingwang 校对:numbbbbb
2.0 翻译+校对:buginux
2.1 校对:shanks,2015-11-01
2.2 翻译+校对:SketchK 2016-05-17
3.0 翻译+校对:mmoaay 2016-09-20
3.0.1:shanks,2016-11-13
除了在之前介绍过的基本运算符,Swift 中还有许多可以对数值进行复杂运算的高级运算符。这些高级运算符包含了在 C 和 Objective-C 中已经被大家所熟知的位运算符和移位运算符。
与 C 语言中的算术运算符不同,Swift 中的算术运算符默认是不会溢出的。所有溢出行为都会被捕获并报告为错误。如果想让系统允许溢出行为,可以选择使用 Swift 中另一套默认支持溢出的运算符,比如溢出加法运算符(&+
)。所有的这些溢出运算符都是以 &
开头的。
自定义结构体、类和枚举时,如果也为它们提供标准 Swift 运算符的实现,将会非常有用。在 Swift 中自定义运算符非常简单,运算符也会针对不同类型使用对应实现。
我们不用被预定义的运算符所限制。在 Swift 中可以自由地定义中缀、前缀、后缀和赋值运算符,以及相应的优先级与结合性。这些运算符在代码中可以像预定义的运算符一样使用,我们甚至可以扩展已有的类型以支持自定义的运算符。
按位左移、右移运算符所描述的。
var signedOverflow = Int8.min
// signedOverflow 等于 Int8 所能容纳的最小整数 -128
signedOverflow = signedOverflow &- 1
// 此时 signedOverflow 等于 127
Int8
型整数能容纳的最小值是 -128
,以二进制表示即 10000000
。当使用溢出减法运算符对其进行减 1
运算时,符号位被翻转,得到二进制数值 01111111
,也就是十进制数值的 127
,这个值也是 Int8
型整数所能容纳的最大值。
对于无符号与有符号整型数值来说,当出现上溢时,它们会从数值所能容纳的最大数变成最小的数。同样地,当发生下溢时,它们会从所能容纳的最小数变成最大的数。
Swift Standard Library Operators Reference。
注意
相对 C 语言和 Objective-C 来说,Swift 的运算符优先级和结合性规则更加简洁和可预测。但是,这也意味着它们相较于 C 语言及其衍生语言并不是完全一致的。在对现有的代码进行移植的时候,要注意确保运算符的行为仍然符合你的预期。
优先级和结合性中详细阐述了这两个特性是如何对中缀运算符的运算产生影响的。
而没有明确放入优先级组的自定义中缀运算符会放到一个默认的优先级组内,其优先级高于三元运算符。
以下例子定义了一个新的自定义中缀运算符 +-
,此运算符属于 AdditionPrecedence
优先组:
infix operator +-: AdditionPrecedence
extension Vector2D {
static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y - right.y)
}
}
let firstVector = Vector2D(x: 1.0, y: 2.0)
let secondVector = Vector2D(x: 3.0, y: 4.0)
let plusMinusVector = firstVector +- secondVector
// plusMinusVector 是一个 Vector2D 实例,并且它的值为 (4.0, -2.0)
这个运算符把两个向量的 x
值相加,同时用第一个向量的 y
值减去第二个向量的 y
值。因为它本质上是属于“相加型”运算符,所以将它放置 +
和 -
等默认的中缀“相加型”运算符相同的优先级组中。关于 Swift 标准库提供的运算符,以及完整的运算符优先级组和结合性设置,请参考 Swift Standard Library Operators Reference。而更多关于优先级组以及自定义操作符和优先级组的语法,请参考运算符声明
注意
当定义前缀与后缀运算符的时候,我们并没有指定优先级。然而,如果对同一个值同时使用前缀与后缀运算符,则后缀运算符会先参与运算。