编程中级 iOS 开发者

Swift 中的运算符函数(将运算符重载为函数)是如何工作的?重载时存在哪些限制,可以创建自己的运算符吗?

用 Hintsage AI 助手通过面试

答案。

Swift 中的运算符函数是实现或重载标准运算符(如 +, -, *, ==, < 等)的功能,还可以创建自定义运算符(例如 %% 或 <|>)。为此,在函数声明中使用关键字 operator。通常会为自己的类型重载运算符,以使其语法更方便和直观。

重载 Vector2D 结构的加法示例:

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

限制:

  • 运算符只能为自定义类型或标准与自定义类型的组合重载。
  • 只能使用 Swift 中允许的符号创建自定义运算符(+*-/&|^%~!=<>.?)。
  • 不要滥用自定义运算符,以免降低代码的可读性。

隐藏考题。

可以为标准类型重载运算符,例如,改变 + 对 Int 的工作含义吗?

回答: 不可以,在 Swift 中无法重载标准类型的全局运算符行为,只能为自定义类型或特定组合进行扩展。例如:

// 错误:对 Int 的重载不会改变现有的语义+ func + (lhs: Int, rhs: Int) -> Int { return lhs - rhs // 不会生效:与现有行为冲突 }

由于不了解此主题的细节而造成的实际错误示例。


故事

在一个项目中创建了自己的运算符 ** (幂),不小心设置了错误的优先级,导致像 2 + 3 ** 2 这样的表达式计算错误。结果:错误的结果,难以调试的 bug。


故事

在一个内部 API 模块中重载了自定义类型的 ==,但没有实现哈希(Hashable),导致在集合 Set 和 Dictionary 中的实例在逻辑相等时被认为是不同的。


故事

在创建自定义运算符时,用户忘记记录其含义。新的开发者误解了运算符的语义,并将其应用于不合适的数据,导致业务逻辑中的难以捕捉的逻辑错误。