Swift 运算符

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 支持 +, -, *, ==

文章已创建 2481

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部