溢出运算符(Overflow Operator)
Swift
的算数运算符出现溢出时会抛出运行时错误
首先Int8
的最大值127
、最小值-128
,UInt8
无符号整形最最大值255
、最小值0
。
print(Int8.max) // 127
print(Int8.min) // -128
print(UInt8.max) // 255
print(UInt8.min) // 0
声明一个变量num
为UInt8.max
,让num
进行+1
操作,这时候编译器会抛出运行时错误,因为num
值超出了UInt8最大值限制,造成运算溢出。
var num: UInt8 = UInt8.max
num += 1 //Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
var num: UInt8 = UInt8.min
num -= 1 //Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
因此Swift提供了溢出运算符来避免运行时错误。
Swift
有溢出运算符(&+
、&-
、&*
),用来支持溢出运算
&+
var numMax: UInt8 = UInt8.max
var a = numMax &+ 1
print(a) // 0
var b = numMax &+ 2
print(b) // 1
&-
var numMin: UInt8 = UInt8.min
var a = numMin &- 1
print(a) // 255
var b = numMin &- 2
print(b) // 254
&*
var numMax: UInt8 = UInt8.max
var a = numMax &* 1
print(a) // 255
var b = numMax &* 2
print(b) // 254
var numMin: UInt8 = UInt8.min
var a1 = numMin &* 1
print(a1) // 0
var b1 = numMin &* 2
print(a1) // 0
运算符重载(Operator Overload)
- 类、结构体、枚举可以为现有的运算符提供自定义功能,这个操作叫做:运算符重载
var v1 = 10
var v2 = 20
let v3 = v1 + v2
上面的代码进行了一组加法运算,那么如果是两个结构体变量能否进行加法操作呢?
struct Point {
var x = 0
var y = 0
}
var p1 = Point(x: 10, y: 20)
var p2 = Point(x: 11, y: 22)
var p3 = p1 + p2 //报错:Protocol 'FloatingPoint' requires that 'Point' conform to 'FloatingPoint'
很明显,上面的操作编译器报错了,编译器默认不支持这样的加法操作,因此Swift
提供了运算符重载方式。
1、可以在最外部自定义一个+
的func
方法:
func +(v1: Point, v2: Point) -> Point {
Point(x: v1.x + v2.x, y: v1.y + v2.y)
}
var p1 = Point(x: 10, y: 20)
var p2 = Point(x: 11, y: 22)
var p3 = p1 + p2
print(p3) // Point(x: 21, y: 42)
var p4 = p1 + p2 + p3
print(p4) // Point(x: 42, y: 84)
2、建议把+
的func
放在对应的结构体、类、枚举内部实现:
struct Point {
var x = 0
var y = 0
static func +(v1: Point, v2: Point) -> Point {
Point(x: v1.x + v2.x, y: v1.y + v2.y)
}
}
-
更多运算符重载定义
运算符也分前缀、中缀、后缀,默认是中缀运算符。
struct Point {
var x = 0
var y = 0
static func +(v1: Point, v2: Point) -> Point {
Point(x: v1.x + v2.x, y: v1.y + v2.y)
}
static func -(v1: Point, v2: Point) -> Point {
Point(x: v1.x - v2.x, y: v1.y - v2.y)
}
static func +=(v1: inout Point, v2: Point) {
p1 = p1 + p2
}
static func ==(v1: Point, v2: Point) -> Bool {
(v1.x == v2.x) && (v1.y == v2.y)
}
//prefix 前缀运算符
static prefix func -(v1: Point) -> Point {
Point(x: -v1.x, y: -v1.y )
}
static prefix func ++(v1: inout Point) -> Point {
v1 += Point(x: 1, y: 1)
return v1
}
//postfix 后缀运算符
static postfix func ++(v1: inout Point) -> Point {
let temp = v1
v1 += Point(x: 1, y: 1)
return temp
}
}
网友评论