编程iOS开发者

操作符重载在Swift中是如何工作的?使用时需要注意哪些细节?

用 Hintsage AI 助手通过面试

答案。

操作符重载 是定义或重载标准(和自定义)操作符对于用户自定义类型的行为的能力。这使得与您的结构和类进行操作的书写更加生动。

特点:

  • 操作符通过关键字 static func 在全局作用域中定义,并且必须使用 operator 修饰符。
  • 进行比较时需要遵循协议(EquatableComparable 等)。
  • 可以创建自定义操作符(infixprefixpostfix),通过相应的关键字来指定它们。
  • 应该避免没有明确必要的情况下过度重载操作符,以提高代码的可读性。

示例:

struct Vector2D { var x: Double var y: Double static func +(lhs: Vector2D, rhs: Vector2D) -> Vector2D { return Vector2D(x: lhs.x + rhs.x, y: lhs.y + rhs.y) } } let a = Vector2D(x: 1, y: 2) let b = Vector2D(x: 3, y: 4) let sum = a + b // Vector2D(x: 4, y: 6)

细节:

  • 重载逻辑操作符需要遵循特定的协议(ExpressibleByBooleanLiteralBooleanType)。
  • 需要为新操作符指定优先级组(precedence group)。
  • 如果重载的操作符与兼容多个协议的类型一起使用,可能会遇到表达式的歧义性。

有陷阱的问题。

可以重载标准操作符,如 +,以便与类对象一起使用吗?需要什么来通过 == 实现自定义结构的比较?

答案: 是的,标准操作符(例如 +、==、<)可以重载以用于用户定义的结构和类。为了通过 == 进行结构/类的比较,类型必须符合 Equatable 协议并实现静态函数 equality:

示例:

struct Point: Equatable { let x: Int let y: Int static func ==(lhs: Point, rhs: Point) -> Bool { return lhs.x == rhs.x && lhs.y == rhs.y } }

因为不了解此主题的细节而导致的实际错误示例。


故事

重载了结构的操作符 ==,但没有实现 hash(into:),并且使用该类型作为 Set 或字典中的键。结果,相同的元素被两次放入集合中或无法找到,因为标准的 Hashable 机制被破坏了。


故事

创建了自定义的 infix 操作符,但没有指定 precedence group。该操作符意外地按照不合逻辑的结合律工作,导致复杂表达式时出现错误。


故事

在项目中引入了操作符 | 来合并模型,但新手经常将其混淆为位操作 OR,导致混淆和布尔标志简单检查中的错误处理。