Swift学习20:如何为类和结构体自定义运算符

张建 lol

运算符重载

  • 类和结构体 可以为现有的运算符提供自定义的实现,称为 运算符重载
1
2
3
4
5
6
7
struct Vector2D {
var x = 0.0,y = 0.0
}

let vector = Vector2D(x: 1.0,y: 2.0)
let anotherVertor = Vector2D(x: 3.0,y: 1.0)
let thirdVertor = vector + anotherVertor

  • 运算符重载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Vector2D {
var x = 0.0,y = 0.0
}

extension Vector2D {
static func + (left:Vector2D,right:Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x,y: left.y + right.y)
}
}

let vector = Vector2D(x: 1.0,y: 2.0)
let anotherVertor = Vector2D(x: 3.0,y: 1.0)
let thirdVector = vector + anotherVertor
print("x is \(thirdVector.x),y is \(thirdVector.y)")

编译运行,查看打印结果:

1
x is 4.0,y is 3.0

一元运算符的重载

  • 类和结构体 也能提供 标准一元运算符 的实现

  • 要实现 前缀 或者 后缀 运算符,需要在声明运算符函数的时候在 func 关键字之前指定 prefix 或者 postfix 限定符

1
2
3
4
5
6
7
8
9
10
11
struct Vector2D {
var x = 0.0,y = 0.0
}
extension Vector2D {
static prefix func - (vector:Vector2D) -> Vector2D {
return Vector2D(x: -vector.x,y: -vector.y)
}
}
let vector = Vector2D(x: 1.0,y: 2.0)
let vector2 = -vector
print("x is \(vector2.x),y is \(vector2.y)")

编译运行,查看打印结果:

1
x is -1.0,y is -2.0

组合赋值运算符重载

  • 组合赋值运算符将赋值运算符 = 与其他运算符进行结合

  • 在实现的时候,需要把运算符的左参数设置成 inout 类型,因为这个参数的值会在运算符函数内直接被修改

1
2
3
4
5
6
7
8
9
extension Vector2D {
static func += (left: inout Vector2D,right:Vector2D) {
left = Vector2D(x: left.x + right.x,y: left.y + right.y)
}
}
var vector3 = Vector2D(x: 1.0, y: 2.0)
let vector4 = Vector2D(x: 2.0,y: 3.0)
vector3 += vector4
print("x is \(vector3.x),y is \(vector3.y)")

编译运行,查看打印结果:

1
x is 3.0,y is 5.0

等价运算符重载

  • 自定义类和结构体不接收等价运算符的默认实现,也就是所谓的 等于 运算符 ==不等于 运算符 !=

  • 要使用等价运算符来检查你自己类型的等价,需要和其他 中缀运算符 一样提供一个 等于 运算符重载,并且遵循标准库的 Equatable 协议

  • swift 为一下自定义类型提供等价运算符合成实现

    • 只有遵循 Equatable 协议存储属性的 结构体
    • 只拥有遵循 Equatable 协议关联类型的 枚举
    • 没有关联类型的枚举
1
2
3
4
5
6
7
8
9
10
11
12
// 等价运算符
struct Vector2D {
var x = 0.0,y = 0.0
}
extension Vector2D: Equatable {
static func == (left:Vector2D,right:Vector2D) -> Bool {
return (left.x == right.x) && (left.y == right.y)
}
}
var vector1 = Vector2D(x: 1.0, y: 2.0)
let vector2 = Vector2D(x: 2.0,y: 3.0)
print(vector1 == vector2)

编译运行,查看打印结果:

1
false

自定义中缀运算符的优先级和结合性

  • 自定义的中缀 infix 运算符也可以指定优先级和结合性

  • 每一个自定义的中缀运算符都属于一个优先级组

  • 优先级组指定了自定义中缀运算符和其他中缀运算符的关系

  • Post title:Swift学习20:如何为类和结构体自定义运算符
  • Post author:张建
  • Create time:2023-02-23 04:02:46
  • Post link:https://redefine.ohevan.com/2023/02/23/Swift课程/Swift学习20:如何为类和结构体自定义运算符/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.