Swift 运算符全解析(2025 版)
“+ – * /” 只是开始 —— 掌握 70+ 运算符,写出 优雅、高效、安全 的 Swift 代码!
一、Swift 运算符分类(6 大类)
| 分类 | 数量 | 示例 |
|---|---|---|
| 算术运算符 | 6 | +, -, *, /, %, ++ |
| 比较运算符 | 6 | ==, !=, >, <, >=, <= |
| 逻辑运算符 | 3 | &&, ||, ! |
| 位运算符 | 6 | &, |, ^, ~, <<, >> |
| 赋值运算符 | 11+ | =, +=, -=, *=, /= |
| 其他运算符 | 20+ | ??, ?:, as, is, ..., ..< |
二、算术运算符(Arithmetic Operators)
let a = 10, b = 3
a + b // 13
a - b // 7
a * b // 30
a / b // 3(整数除法)
a % b // 1(余数)
// Swift 3+ 移除了 ++ 和 --
var x = 5
x += 1 // 推荐写法
注意:
/在Int间是整除,要浮点除用Double
Double(a) / Double(b) // 3.333...
三、比较运算符(Comparison Operators)
1 == 1 // true
1 != 2 // true
2 > 1 // true
1 < 2 // true
1 >= 1 // true
1 <= 2 // true
特殊:元组比较(按序逐个比较)
(1, "zebra") < (2, "apple") // true(1<2)
("dog", 3) < ("dog", 5) // true(3<5)
字符串比较(字典序)
"swift" < "Swift" // false(大写在前)
四、逻辑运算符(Logical Operators)
true && false // false
true || false // true
!true // false
短路求值(Short-circuit)
false && expensiveFunc() // expensiveFunc() 不会执行
true || anotherFunc() // anotherFunc() 不会执行
五、位运算符(Bitwise Operators)
| 运算符 | 名称 | 示例 |
|---|---|---|
& | 按位与 | 0b1010 & 0b1100 = 0b1000 |
| | 按位或 | 0b1010 | 0b1100 = 0b1110 |
^ | 按位异或 | 0b1010 ^ 0b1100 = 0b0110 |
~ | 按位取反 | ~0b0001 = 0b...1110 |
<< | 左移 | 0b0001 << 2 = 0b0100 |
>> | 右移 | 0b0100 >> 1 = 0b0010 |
let mask: UInt8 = 0b0011_1100
let value: UInt8 = 0b1010_1010
let result = value & mask // 0b0010_1000
六、赋值运算符(Assignment Operators)
var x = 10
x += 5 // 15
x -= 3 // 12
x *= 2 // 24
x /= 4 // 6
x %= 5 // 1
复合赋值不返回值的特性
var a = 1
var b = 2
// if (a = b) { } // 错误!赋值不返回布尔值
if a == b { }
七、核心高级运算符
1. 空合运算符 ??(Nil-Coalescing)
let name = optionalName ?? "匿名"
let score = userScore ?? 0
2. 三元运算符 ?:
let result = score >= 60 ? "及格" : "挂科"
3. 范围运算符(Range Operators)
| 运算符 | 名称 | 示例 |
|---|---|---|
... | 闭区间 | 1...5 → 1,2,3,4,5 |
..< | 半开区间 | 1..<5 → 1,2,3,4 |
..< | 单侧区间 | ..<5 → 从头到 4 |
for i in 1...5 { print(i) }
let sub = array[2..<5]
八、类型相关运算符
| 运算符 | 功能 |
|---|---|
as | 强制类型转换(确定成功) |
as? | 安全类型转换(返回可选) |
as! | 强制解包转换(失败崩溃) |
is | 类型检查 |
let obj: Any = "hello"
if let str = obj as? Heres {
print(str.count)
}
九、溢出运算符(Overflow Operators)
防止整数溢出崩溃
var max = UInt8.max // 255
// max + 1 // 溢出崩溃
max &+ 1 // 溢出加法 → 0
max &- 1 // 溢出减法 → 254
max &* 2 // 溢出乘法 → 254
十、自定义运算符(Custom Operators)
1. 声明新运算符
// 前缀
prefix operator +++
// 中缀
infix operator +-: AdditionPrecedence
// 后缀
postfix operator ***
2. 实现运算符
prefix func +++ (vector: inout Vector) {
vector.x += 1
vector.y += 1
}
var v = Vector(x: 1, y: 2)
+++v // x=2, y=3
3. 运算符优先级组
precedencegroup ExponentiationPrecedence {
higherThan: MultiplicationPrecedence
lowerThan: BitwiseShiftPrecedence
associativity: right
assignment: true
}
infix operator **: ExponentiationPrecedence
func ** (base: Double, exponent: Double) -> Double {
return pow(base, exponent)
}
print(2 ** 3 ** 2) // 512(右结合)
十一、运算符重载(Operator Overloading)
struct Vector {
var x, y: Double
}
// 重载 +
static func + (lhs: Vector, rhs: Vector) -> Vector {
return Vector(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
}
// 重载 ==
static func == (lhs: Vector, rhs: Vector) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
let v1 = Vector(x: 1, y: 2)
let v2 = Vector(x: 3, y: 4)
let v3 = v1 + v2
十二、智能运算符技巧
1. 安全除法
func / (lhs: Int, rhs: Int) -> Double? {
return rhs != 0 ? Double(lhs) / Double(rhs) : nil
}
2. 链式比较(Python 风格)
if 1 < x && x < 10 { } // 不能写 1 < x < 10
3. 可选链 + 运算符
let area = shape?.bounds?.area ?? 0
十三、运算符速查表
| 类别 | 运算符 |
|---|---|
| 算术 | + - * / % |
| 比较 | == != > < >= <= |
| 逻辑 | && || ! |
| 位运算 | & | ^ ~ << >> |
| 赋值 | = += -= *= /= %= |
| 范围 | ... ..< |
| 空合 | ?? |
| 三元 | ?: |
| 类型 | as as? as! is |
| 溢出 | &+ &- &* &/ &% |
十四、实战小项目:向量运算库
struct Vector2D {
var x, y: Double
static func + (a: Vector2D, b: Vector2D) -> Vector2D {
return Vector2D(x: a.x + b.x, y: a.y + b.y)
}
static func - (a: Vector2D, b: Vector2D) -> Vector2D {
return Vector2D(x: a.x - b.x, y: a.y - b.y)
}
static prefix func - (v: Vector2D) -> Vector2D {
return Vector2D(x: -v.x, y: -v.y)
}
static func * (v: Vector2D, scalar: Double) -> Vector2D {
return Vector2D(x: v.x * scalar, y: v.y * scalar)
}
var magnitude: Double {
return (x*x + y*y).squareRoot()
}
}
// 使用
let a = Vector2D(x: 3, y: 4)
let b = Vector2D(x: 1, y: 2)
let c = a + b * 2 - Vector2D(x: 0, y: 1)
print(c.magnitude)
十五、练习题(当场写!)
// 1. 实现幂运算符 **
infix operator ** { associativity right precedence 160 }
func ** (base: Int, power: Int) -> Int {
// 你的代码
}
// 2. 实现安全除法,返回可选
func ??/ (a: Int, b: Int) -> Int? {
// 你的代码
}
// 3. 重载 String 的 + 实现重复
extension String {
static func + (lhs: String, rhs: Int) -> String {
// "hi" + 3 → "hihihi"
}
}
答案(展开查看)
点击查看答案
// 1.
infix operator ** { associativity right precedence 160 }
func ** (base: Int, power: Int) -> Int {
guard power >= 0 else { return 0 }
return stride(from: 0, power, by: 1).reduce(1) { $0 * base }
}
// 2.
func ??/ (a: Int, b: Int) -> Int? {
return b != 0 ? a / b : nil
}
// 3.
extension String {
static func + (lhs: String, rhs: Int) -> String {
return String(repeating: lhs, count: max(0, rhs))
}
}
总结:运算符使用黄金法则
| 法则 | 说明 |
|---|---|
1. 优先用 ?? 而不是 if let | 简洁 |
2. 用 ... 闭区间遍历 | 包含末尾 |
3. 避免 as! | 改用 as? |
| 4. 自定义运算符要谨慎 | 影响可读性 |
5. 溢出运算用 &+ | 防止崩溃 |
你已完全掌握 Swift 运算符!
回复关键词继续学习:
Swift 自定义运算符实战Swift 运算符优先级详解Swift 泛型运算符SwiftUI 动画运算符
现在就实现一个 Vector3D 支持 +, -, *, ==!