swift 之运算符

2020-01-15  本文已影响0人  枯树恋

基本概念

赋值和算术运算符

swift支持c中大多数标准运算符,并且:


print(3 % 2) // 1
print(-3 % 2) // -1
print(3 % -2) // 1

溢出运算符

 var a: UInt8 = 0xff
 a &+= 1
 print(a) // 0
 a = 0
// a -= 1  error
 a &-= 1
 print(a) // 255

合并空值运算符

 //正常用法
 var a : Int? = nil
 var b: Int = 255

 print(a ?? b ) // 255
 a = 20
 print(a ?? b ) // 20
 print(type(of: a ?? b)) // Int

 //这样不会报错,但是明显c和d类型不同
 var c: Int? = nil
 let d: String = "abc"
 print(c ?? d) // abc

 //Expression type '(_) -> _' is ambiguous without more context
// print(type(of: c ?? d))

区间运算符

位运算

常见应用:

func swap(_ a: inout Int,_ b: inout Int) {
    a = a ^ b
    b = a ^ b
    a = a ^ b
 }
 var a = 10
 var b = 8
 print("a = \(a) b = \(b)")
 swap(&a, &b)
 print("a = \(a) b = \(b)")
 func countOfOnes(_ num: UInt) -> UInt {
    var count: UInt = 0
    var temp = num
    while temp != 0 {
        count += 1
        temp = temp & (temp - 1)
    }
    return count
 }
 func isPowerOfTwo(_ num: UInt) -> Bool {
    return num & (num - 1) == 0
 }
 func findLostNum(_ nums: [UInt]) -> UInt {
    return nums.reduce(0) { $0 ^ $1}
 }
func findTwoLostNumbers(_ nums: [UInt]) -> (UInt,UInt) {
    let temp = nums.reduce(0) { $0 ^ $1}
    var flag: UInt = 1
    while temp & flag == 0 {
        flag <<= 1
    }
    var ans: (UInt,UInt) = (0,0)
    for num in nums {
        if num & flag == 0 {
            ans.0 ^= num
        } else {
            ans.1 ^= num
        }
    }
    return ans
 }

运算符重载

 struct Vector2D {
    var x: Int
    var y: Int
    var description: String {
        return "(x: \(x), y: \(y))"
    }
 }

 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, y: 2)
 let another = Vector2D(x: 2, y: 5)
 let combineVector = vector + another
 print("vector1: \(vector.description) another: \(another.description) combineVector: \(combineVector.description)")
 //vector1: (x: 1, y: 2) another: (x: 2, y: 5) combineVector: (x: 3, y: 7)
 extension Vector2D {
    static prefix func - (vector: Vector2D) -> Vector2D {
        return Vector2D(x: -vector.x, y: -vector.y)
    }
 }

 let positive = Vector2D(x: 3, y: 5)
 let negative = -positive
 print("positive: \(positive.description) negative: \(negative.description)") //positive: (x: 3, y: 5) negative: (x: -3, y: -5)
 extension Vector2D {
    static func += (left: inout Vector2D, right: Vector2D) {
        left.x += right.x
        left.y += right.y
    }
 }

 var original = Vector2D(x: 2, y: 3)
 let toAdd = Vector2D(x: 4, y: 5)
 original += toAdd
 print(original.description) //(x: 6, y: 8)
 extension Vector2D: Equatable {
    static func == (left: Vector2D, right: Vector2D) -> Bool {
        return left.x == right.x && left.y == right.y
    }
 }

自定义运算符

 prefix operator ++
 extension Vector2D {
    static prefix func ++ (vector: inout Vector2D) {
        vector += vector
    }
 }
var vector = Vector2D(x: 1, y: 2)
 ++vector
 print("vector: \(vector.description)") //vector: (x: 2, y: 4)
 infix operator +- : AdditionPrecedence
 extension Vector2D {
    static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x + right.x, y: left.y - right.y)
    }
 }

 infix operator *^: MultiplicationPrecedence
 extension Vector2D {
    static func *^ (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x * right.x, y: left.y * left.y + right.y * right.y)
    }
 }

 let first = Vector2D(x: 1, y: 2)
 let second = Vector2D(x: 3, y: 7)
 let third = Vector2D(x: 2, y: 2)
 //根据优先级组:先算 *^ 再算 +-
 print("vector: \((first +- second *^ third).description)") //vector: (x: 7, y: -51)
* 使用自定义优先级组
infix operator +- : AdditionPrecedence
 extension Vector2D {
    static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x + right.x, y: left.y - right.y)
    }
 }
  precedencegroup UserDefinePrecedence {
     associativity: left
     lowerThan: AdditionPrecedence
  }
 infix operator *^: UserDefinePrecedence
 extension Vector2D {
    static func *^ (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x * right.x, y: left.y * left.y + right.y * right.y)
    }
 }
 
 let first = Vector2D(x: 1, y: 2)
 let second = Vector2D(x: 3, y: 7)
 let third = Vector2D(x: 2, y: 2)
 //根据优先级组:先算 +- 再算 *^
 print("vector: \((first +- second *^ third).description)") //vector: (x: 8, y: 29)
上一篇下一篇

猜你喜欢

热点阅读