Advanced Operators and Custom Operators
27.1 Bitwise and Overflow Operators
let initial: UInt8 = 0b0000_1111
~initial // 0b1111_0000
initial & 0b0011_1100 // AND
initial | 0b1111_0000 // OR
initial ^ 0b1111_1111 // XOR
initial << 2, initial >> 1
let pink: UInt32 = 0xCC6699
let red = (pink & 0xFF0000) >> 16 // 0xCC
var max = UInt8.max
max = max &+ 1 // 0 (wraps instead of trapping)
let (result, overflow) = Int.max.addingReportingOverflow(1)
Int.max.multipliedFullWidth(by: 2)27.2 Operator Overloading
struct Vector2D: Equatable {
var x = 0.0, y = 0.0
static func + (lhs: Vector2D, rhs: Vector2D) -> Vector2D { Vector2D(x: lhs.x + rhs.x, y: lhs.y + rhs.y) }
static prefix func - (v: Vector2D) -> Vector2D { Vector2D(x: -v.x, y: -v.y) }
static func += (lhs: inout Vector2D, rhs: Vector2D) { lhs = lhs + rhs }
static func * (v: Vector2D, k: Double) -> Vector2D { Vector2D(x: v.x * k, y: v.y * k) }
}
var v = Vector2D(x: 1, y: 2) + Vector2D(x: 3, y: 4)
v += Vector2D(x: 1, y: 1)
let inverted = -v27.3 Custom Operators and Precedence
Use custom operators sparingly. They hurt readability unless they're domain-standard (math, parsers, DSLs).
prefix operator +++
infix operator **: ExponentiationPrecedence
precedencegroup ExponentiationPrecedence {
higherThan: MultiplicationPrecedence
associativity: right
}
infix operator |>: ForwardPipePrecedence
precedencegroup ForwardPipePrecedence { associativity: left; lowerThan: TernaryPrecedence }
extension Vector2D {
static prefix func +++ (v: inout Vector2D) -> Vector2D { v += v; return v }
}
func ** (base: Double, exp: Double) -> Double { pow(base, exp) }
func |> <A, B>(value: A, f: (A) -> B) -> B { f(value) }
2 ** 3 ** 2 // 512 (right-associative)
"swift" |> { $0.uppercased() } |> { $0 + "!" }