5. Swift 运算符的拓展.png

溢出运算符

  • Swift 的算数运算符出现溢出时会抛出运行时错误
  • Swift 有溢出运算符(&+、&-、&*),用来支持溢出运算
  1. var min = UInt8.min
  2. print(min &- 1) // 255, Int8.max
  3. var max = UInt8.max
  4. print(max &+ 1) // 0, Int8.min
  5. print(max &* 2) // 254, 等价于 max &+ max

运算符重载

运算符重载:类、结构体、枚举可以为现有的运算符提供自定义的实现

  1. struct Point {
  2. var x: Int
  3. var y: Int
  4. // Point(x: 1, y: 2) + Point(x: 1, y: 2) => Point(x: 2, y: 4)
  5. static func + (p1: Point, p2: Point) -> Point {
  6. return Point(x: p1.x + p2.x, y: p1.y + p2.y)
  7. }
  8. // Point(x: 1, y: 2) - Point(x: 1, y: 2) => Point(x: 0, y: 0)
  9. static func - (p1: Point, p2: Point) -> Point {
  10. return Point(x: p1.x - p2.x, y: p1.y - p2.y)
  11. }
  12. // - Point(x: 1, y: 2) => Point(x: -1, y: -2)
  13. static prefix func - (p: Point) -> Point {
  14. return Point(x: -p.x, y: -p.y)
  15. }
  16. // Point(x: 1, y: 2) += Point(x: 1, y: 2) => Point(x: 2, y: 4)
  17. static func += (p1: inout Point, p2: Point) {
  18. p1 = p1 + p2
  19. }
  20. // ++ Point(x: 1, y: 2) => Point(x: 2, y: 3)
  21. static prefix func ++ (p: inout Point) -> Point {
  22. p += Point(x: 1, y: 1)
  23. return p
  24. }
  25. // Point(x: 1, y: 2) ++ => Point(x: 1, y: 2)
  26. static postfix func ++ (p: inout Point) -> Point {
  27. let tmp = p
  28. p += Point(x: 1, y: 1)
  29. return tmp
  30. }
  31. // Point(x: 1, y: 2) == Point(x: 1, y: 2) => true
  32. static func == (p1: Point, p2: Point) -> Bool {
  33. return (p1.x == p2.x) && (p1.y == p2.y)
  34. }
  35. }
  36. var p1 = Point(x: 10, y: 10)
  37. var p2 = Point(x: 20, y: 20)
  38. var p3 = p1 + p2
  39. print(p3) // Point(x: 30, y: 30)

自定义运算符

不推荐使用自定义运算符,太危险
**
prefix 表示该运算符会位于表达式前面
postfix 表示该运算符会位于表达式后面
infix 表示该操作符会位于两个表达式的中间

  1. prefix operator ~
  2. prefix func ~(v: String?) -> String {
  3. return v == nil ? "" : v!
  4. }
  5. var a: String?
  6. print(~a)
  1. postfix operator ~
  2. postfix func ~(v: String?) -> String {
  3. return v == nil ? "" : v!
  4. }
  5. var a: String?
  6. print(a~)

优先级组

precedencegroup 定义了一个优先级组,表示操作符优先级别

  1. precedencegroup YourPrecedenceGroupName {
  2. /**
  3. 较高优先级组的名称,优先级更高的运算符将优先参与运算
  4. eg. MultiplicationPrecedence: *(乘) /(除)
  5. */
  6. lowerThan: MultiplicationPrecedence
  7. /**
  8. 较低优先级组的名称,只可以引用当前模块外的优先级组
  9. eg. AdditionPrecedence: +(加) -(减)
  10. */
  11. higherThan: AdditionPrecedence
  12. /**
  13. 结合性,可选值:left、right、none(默认值)
  14. 比如,减法是左边减去右边,而不是右边减去左边
  15. */
  16. associativity: left
  17. /**
  18. 赋值性,可选值:true、false(默认值)
  19. */
  20. assignment: true
  21. }

举例说明

  1. import Darwin
  2. precedencegroup MyPrecedence {
  3. associativity: left
  4. higherThan: MultiplicationPrecedence
  5. }
  6. infix operator *^ : MyPrecedence
  7. func *^ (lhs: Double, rhs: Double) -> Double {
  8. return pow(lhs, rhs)
  9. }
  10. print(2 *^ 4) // 16.0

参考文章