溢出运算符
- Swift的算数运算符出现溢出时会抛出运行时错误
- Swift有溢出运算符(&+、&-、&*),用来支持溢出运算
var umin = UInt8.min //0
var umax = UInt8.max //255
var min = Int8.min //-128
var max = Int8.max //127
print(umax &+ 1) //0
print(umax &* 2) //254
UInt8.max + 1图解:
结果是0
UInt8.max * 2图解:
结果是127
运算符重载
- 类,结构体,枚举可以为现有的运算符提供自定义的实现,这个操作叫做运算符重载
preifx:前缀运算符
postfix:后缀运算符
Equatable
- 要想得知2个实例是否等价,一般做法是遵守Equatable 协议,重载== 运算符
- 与此同时,等价于重载了 != 运算符
- Swift为以下类型提供默认的Equatable 实现 :
- 没有关联类型的枚举
enum Answer {
case wrong
case right
}
var s1 = Answer.wrong
var s2 = Answer.right
print(s1 == s2)
有关联类型会报错:
2. 只拥有遵守 Equatable 协议关联类型的枚举
//Int, String都遵守Equatable协议
enum Answer : Equatable {
case wrong(Int, String)
case right
}
var s1 = Answer.wrong(10, "Jack")
var s2 = Answer.wrong(10, "Jack")
print(s1 == s2)
//Cat()类型不遵守Equatable协议,会报错
3. 只拥有遵守 Equatable 协议存储属性的结构体
- 引用类型比较存储的地址值是否相等(是否引用着同一个对象),使用恒等运算符=== 、!==
class Person : Equatable {
var age: Int
init(age: Int) {
self.age = age
}
static func == (lhs: Person, rhs: Person) -> Bool{
return lhs.age == rhs.age
}
}
var p1 = Person(age: 10)
var p2 = Person(age: 10)
print(p1 == p2) //true
print(p1 === p2) //false : ===比较的是存储地址值,看是否是同一个对象,虽然p1和p2的age属性值相同,但不是同一个对象,所以为false
Comparable
- 要想比较2个实例的大小,一般做法是:
- 遵守Comparable协议
- 重载相应的运算符
自定义运算符(Customer Operator)
- 可以自定义新的运算符,在全局作用域使用operator进行声明
associativity: left表示从左到右进行计算,right表示从右到左进行计算,none表示不能有两个以上自定义的运算符在一条运算语句中同时使用
assignment:
class Person {
var age = 0
var point: Point = Point()
}
var p: Person? = Person()
p?.point +- Point(x: 10, y: 20) //这个运算符跟赋值运算符一样当可选项p为nil时,不会继续进行运算,也就是Point(x: 10, y: 20)不会初始化
- Apple文档参考:
- https://developer.apple.com/documentation/swift/swift_standard_library/operator_declarations
- https://docs.swift.org/swift- book/ReferenceManual/Declarations.html#ID380
prefix operator +++
prefix func +++ (_ i: inout Int) {
i += 2
}
var age = 10
+++age
print(age) //12
infix operator +- : PlusMinusPrecedence
precedencegroup PlusMinusPrecedence {
associativity: none
higherThan: AdditionPrecedence
lowerThan: MultiplicationPrecedence
assignment: true
}
struct Point {
var x: Int, y: Int
static func +- (left: Point, right: Point) -> Point{
return Point(x: left.x + right.x, y: left.y + right.y)
}
static func +- (left: Point?, right: Point) -> Point {
print("+-")
return Point(x: left?.x ?? 0 + right.x, y: left?.y ?? 0 + right.y)
}
}
struct Person {
var point : Point
}
var person: Person? = Person(point: Point(x: 11, y: 22))
var p1 = person?.point +- Point(x: 10, y: 20)
print(p1 ?? Point(x: 0, y: 0)) // Point(x: 21, y: 42)
var personOther: Person = Person(point: Point(x: 12, y: 23))
var p2 = personOther.point +- Point(x: 10, y: 20)
print(p2) // Point(x: 22, y: 43)