Swift:高级运算符

2018-07-25  本文已影响22人  伯wen

中文文档

一、位运算符

位操作符通常在诸如图像处理和创建设备驱动等底层开发中使用,使用它可以单独操作数据结构中原始数据的比特位。在使用一个自定义的协议进行通信的时候,运用位运算符来对原始数据进行编码和解码也是非常有效的。

1、按位取反运算符
按位取反运算符
let initialBits: UInt8 = 0b00001111 
let invertedBits = ~initialBits  // 等于 0b11110000 
2、按位与运算符
按位与运算符
let firstSixBits: UInt8 = 0b11111100 
let lastSixBits: UInt8  = 0b00111111 
let middleFourBits = firstSixBits & lastSixBits  // 等于 00111100 
3、按位或运算
按位或运算
let someBits: UInt8 = 0b10110010 
let moreBits: UInt8 = 0b01011110 
let combinedbits = someBits | moreBits  // 等于 11111110 
4、按位异或运算符
按位异或运算符
let firstBits: UInt8 = 0b00010100 
let otherBits: UInt8 = 0b00000101 
let outputBits = firstBits ^ otherBits  // 等于 00010001 
5、按位左移/右移运算符
6、无符整型的移位操作
已经存在的比特位向左或向右移动指定的位数。
被移出整型存储边界的的位数直接抛弃,移动留下的空白位用零0来填充。这种方法称为逻辑移位。
无符整型的移位操作
let shiftBits: UInt8 = 4   // 即二进制的00000100 
shiftBits << 1             // 00001000 
shiftBits << 2             // 00010000 
shiftBits << 5             // 10000000 
shiftBits << 6             // 00000000 
shiftBits >> 2             // 00000001 
let pink: UInt32 = 0xCC6699 
let redComponent = (pink & 0xFF0000) >> 16    // redComponent 是 0xCC, 即 204 
let greenComponent = (pink & 0x00FF00) >> 8   // greenComponent 是 0x66, 即 102 
let blueComponent = pink & 0x0000FF           // blueComponent 是 0x99, 即 153 
7、有符整型的移位操作
对有符整型按位右移时,使用符号位(正数为0,负数为1)填充空白位。

二、溢出运算符

var potentialOverflow = Int16.max 
// potentialOverflow 等于 32767, 这是 Int16 能承载的最大整数 
potentialOverflow += 1 
// 噢, 出错了 
溢出加法 &+
溢出减法 &-
溢出乘法 &*
溢出除法 &/
溢出求余 &%
1、值的上溢出
var willOverflow = UInt8.max 
// willOverflow 等于UInt8的最大整数 255 
willOverflow = willOverflow &+ 1 
// 这时候 willOverflow 等于 0 
2、值的下溢出
var willUnderflow = UInt8.min 
// willUnderflow 等于UInt8的最小值0 
willUnderflow = willUnderflow &- 1 
// 此时 willUnderflow 等于 255 
var signedUnderflow = Int8.min 
// signedUnderflow 等于最小的有符整数 -128 
signedUnderflow = signedUnderflow &- 1 
// 如今 signedUnderflow 等于 127 
3、除零溢出
let x = 1 
let y = x / 0 
let x = 1 
let y = x &/ 0 
// y 等于 0 

三、优先级和结合性

四、运算符函数

struct Vector2D { 
    var x = 0.0, y = 0.0 
} 
func + (left: Vector2D, right: Vector2D) -> Vector2D { 
    return Vector2D(x: left.x + right.x, y: left.y + right.y) 
} 
let v1 = Vector2D(x: 1, y: 2)
let v2 = Vector2D(x: 3, y: 4)
print(v1 + v2)        // 打印: Vector2D(x: 4.0, y: 6.0)
2、前置和后置运算符
prefix func - (vector: Vector2D) -> Vector2D { 
    return Vector2D(x: -vector.x, y: -vector.y) 
} 
print(-v1)        // 打印: Vector2D(x: -1.0, y: -2.0)
3、组合赋值运算符
func += (inout left: Vector2D, right: Vector2D) { 
    left = left + right 
} 
var a = Vector2D(x: 1.0, y: 2.0) 
let b = Vector2D(x: 3.0, y: 4.0) 
a += b 
// a 现在为 (4.0, 6.0) 

注意:默认的赋值符(=)是不可重载的。只有组合赋值符可以重载。三目条件运算符 (a ? b : c) 也是不可重载。

4、等价运算符
extension Vector2D: Equatable {
    static func == (left: Vector2D, right: Vector2D) -> Bool {
        return (left.x == right.x) && (left.y == right.y)
    }
}

示例里同时也实现了“不等”运算符(!=),它简单地将“相等”运算符的结果进行取反后返回。

let twoThree = Vector2D(x: 2.0, y: 3.0)
let anotherTwoThree = Vector2D(x: 2.0, y: 3.0)
if twoThree == anotherTwoThree {
    print("These two vectors are equivalent.")
}
// 打印 “These two vectors are equivalent.”
只拥有遵循 Equatable 协议存储属性的结构体;
只拥有遵循 Equatable 协议关联类型的枚举;
没有关联类型的枚举。
struct Vector3D: Equatable {
    var x = 0.0, y = 0.0, z = 0.0
}

let twoThreeFour = Vector3D(x: 2.0, y: 3.0, z: 4.0)
let anotherTwoThreeFour = Vector3D(x: 2.0, y: 3.0, z: 4.0)
if twoThreeFour == anotherTwoThreeFour {
    print("These two vectors are also equivalent.")
}
// Prints "These two vectors are also equivalent."

五、自定义运算符

注意
以下这些标记 =->///**/.<(前缀运算符)、&??(中缀运算符)、>(后缀运算符)、!? 是被系统保留的。这些符号不能被重载,也不能用于自定义运算符。

prefix:    前置运算符
infix:     中置运算符
postfix:   后置运算符
prefix operator +++
extension Vector2D {
    static prefix func +++ (vector: inout Vector2D) -> Vector2D {
        vector += vector
        return vector
    }
}

var toBeDoubled = Vector2D(x: 1.0, y: 4.0)
let afterDoubling = +++toBeDoubled
// toBeDoubled 现在的值为 (2.0, 8.0)
// afterDoubling 现在的值也为 (2.0, 8.0)
1、自定义中缀运算符的优先级
infix operator +-: AdditionPrecedence
extension Vector2D {
    static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x + right.x, y: left.y - right.y)
    }
}
let firstVector = Vector2D(x: 1.0, y: 2.0)
let secondVector = Vector2D(x: 3.0, y: 4.0)
let plusMinusVector = firstVector +- secondVector
// plusMinusVector 是一个 Vector2D 实例,并且它的值为 (4.0, -2.0)
2、定义优先级别名
// >>>操作符, 优先级别名
infix operator >>> : ATPrecedence
precedencegroup ATPrecedence { //定义运算符优先级ATPrecedence
    associativity: left 
    higherThan: AdditionPrecedence 
    lowerThan: MultiplicationPrecedence
}
associativity: left 表示左结合
higherThan 优先级高于 AdditionPrecedence 这个是加法的类型
lowerThan 优先级低于 MultiplicationPrecedence 乘除
infix operator || : LogicalDisjunctionPrecedence
infix operator && : LogicalConjunctionPrecedence
infix operator < : ComparisonPrecedence
infix operator <= : ComparisonPrecedence
infix operator > : ComparisonPrecedence
infix operator >= : ComparisonPrecedence
infix operator == : ComparisonPrecedence
infix operator != : ComparisonPrecedence
infix operator === : ComparisonPrecedence
infix operator !== : ComparisonPrecedence
infix operator ~= : ComparisonPrecedence
infix operator ?? : NilCoalescingPrecedence
infix operator + : AdditionPrecedence
infix operator - : AdditionPrecedence
infix operator &+ : AdditionPrecedence
infix operator &- : AdditionPrecedence
infix operator | : AdditionPrecedence
infix operator ^ : AdditionPrecedence
infix operator * : MultiplicationPrecedence
infix operator / : MultiplicationPrecedence
infix operator % : MultiplicationPrecedence
infix operator &* : MultiplicationPrecedence
infix operator & : MultiplicationPrecedence
infix operator << : BitwiseShiftPrecedence
infix operator >> : BitwiseShiftPrecedence
infix operator ..< : RangeFormationPrecedence
infix operator ... : RangeFormationPrecedence
infix operator *= : AssignmentPrecedence
infix operator /= : AssignmentPrecedence
infix operator %= : AssignmentPrecedence
infix operator += : AssignmentPrecedence
infix operator -= : AssignmentPrecedence
infix operator <<= : AssignmentPrecedence
infix operator >>= : AssignmentPrecedence
infix operator &= : AssignmentPrecedence
infix operator ^= : AssignmentPrecedence
infix operator |= : AssignmentPrecedence
上一篇 下一篇

猜你喜欢

热点阅读