1、簡介
Swift中類或結構體可以對已有的運算符進行自定義實現(xiàn)喻括,賦予另外一種功能邀杏。可以成為運算符函數(shù)唬血,即運算符重載望蜡。
2、運算符函數(shù)
2.1拷恨、雙目運算符
下面將通過例子展示自定義結構體如何實現(xiàn)加法運算符(+)和減法運算符(-)脖律,加法運算符和減法運算符是雙目運算符,可以對兩個值進行運算腕侄,并且在兩個值之間小泉。
例子中定義了一個Coordinate的結構體,包含x和y兩個值冕杠,表示平面坐標系上面的點微姊。
struct Coordinate {
var x: Double = 0.0
var y: Double = 0.0
}
extension Coordinate {
static func +(lhs: Coordinate, rhs: Coordinate) -> Coordinate {
coordinate = Coordinate(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
}
static func -(lhs: Coordinate, rhs: Coordinate) -> Coordinate {
coordinate = Coordinate(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
}
}
上述兩個運算符函數(shù)被定義為Coordinate的類方法,運算符函數(shù)名和重載的運算符保持一致分预。加法運算符(+)和減法運算符(-)是雙目運算符兢交,因此接收兩個Coordinate類型的參數(shù),返回一個Coordinate類型的返回值笼痹。
上述兩個類方法可以在任意兩個Coordinate實例之間作為中綴運算符使用:
let point = Coordinate(x: 1.0, y: 1.0)
let anotherPoint = Coordinate(x: 2.0, y: 2.0)
let resultPoint1 = point + anotherPoint
let resultPoint2 = point - anotherPoint
print(resultPoint1)
print(resultPoint2)
這個例子中實現(xiàn)了(1.0魁淳,1.0)和(2.0,2.0)兩個點的相加和相減与倡,得到兩個新的點(3.0界逛,3.0)和(-1.0,-1.0)
Coordinate(x: 3.0, y: 3.0)
Coordinate(x: -1.0, y: -1.0)
2.2纺座、前綴運算符息拜、后綴運算符
2.1節(jié)的兩個運算符函數(shù)實現(xiàn)了雙目運算的自定義實現(xiàn)。類和結構體也可以實現(xiàn)單目運算符,單目運算符只運算一個值少欺。運算符出現(xiàn)在值之前為前綴運算符喳瓣,出現(xiàn)在值之后為后綴運算符。
實現(xiàn)單目運算符需在在聲明運算符函數(shù)時在func關鍵字之前添加prefix(前綴)(例如:-a)或postfix(后綴)(例如:bT薇稹)修飾符畏陕。
extension Coordinate {
static prefix func +(coordinate: Coordinate) -> Coordinate {
return Coordinate(x: +coordinate.x, y: +coordinate.y)
}
static prefix func -(coordinate: Coordinate) -> Coordinate {
return Coordinate(x: -coordinate.x, y: -coordinate.y)
}
}
上述的兩個運算符函數(shù)為單目運算運算符函數(shù)。由于是前綴運算符仿滔,需要在
func關鍵字之前加上prefix修飾符惠毁。
上述兩個運算符函數(shù)只對Coordinate實例的x、y做簡單的正負改變:
let point = Coordinate(x: 1.0, y: 1.0)
let anotherPoint = Coordinate(x: 2.0, y: 2.0)
print(-point)
print(+anotherPoint)
這個例子中對(1.0崎页,1.0)和(2.0鞠绰,2.0)兩個點進行正負運算,輸出結果為:
Coordinate(x: -1.0, y: -1.0)
Coordinate(x: 2.0, y: 2.0)
2.3飒焦、復合賦值運算符
復合賦值運算符是賦值運算符(=)和其他運算符進行結合蜈膨。例如加法運算符(+)和賦值運算符(=)相結合組成加法賦值運算符(=+)。復合賦值運算符函數(shù)需要將左值進行inout關鍵修飾牺荠,因為在函數(shù)內部要對左值進行直接的修改翁巍。
extension Coordinate {
static func +=(lhs: inout Coordinate, rhs: Coordinate) {
lhs = Coordinate(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
}
static func -=(lhs: inout Coordinate, rhs: Coordinate) {
lhs = Coordinate(x: lhs.x - rhs.y, y: lhs.y - rhs.y)
}
}
上述兩個運算符函數(shù)實現(xiàn)了加法賦值運算符和減法賦值運算符的自定義。
var point = Coordinate(x: 1.0, y: 1.0)
let anotherPoint = Coordinate(x: 2.0, y: 2.0)
point += anotherPoint
print(point)
由于符合賦值運算符函數(shù)的左值進行了inout修飾休雌,運算的結果是對左值進行直接的修改灶壶,輸入結果為:
Coordinate(x: 3.0, y: 3.0)
注意:不能對默認的賦值運算符(=)進行重載,只有復合賦值運算符可以重載挑辆。三目條件運算符(a ? b : c)也不能進行重載例朱。
2.4、等價運算符
自定義類和結構體沒有對等價運算符進行默認的實現(xiàn)鱼蝉。等價運算符一般被稱為相等運算符(==)和不等運算符(!=)洒嗤。
對于自定義的類型,Swift無法進行判等運算魁亦,因為“相等”的含義取決于自定義類型在代碼中扮演的角色渔隶。為了使自定義類型能夠進行等價運算,我們可以對等價運算符進行自定義實現(xiàn)洁奈。
extension Coordinate {
static func ==(lhs: Coordinate, rhs: Coordinate) -> Bool {
if lhs.x == rhs.x && lhs.y == rhs.y {
return true
}
return false
}
static func !=(lhs: Coordinate, rhs: Coordinate) -> Bool {
if lhs.x != rhs.x || lhs.y != rhs.y {
return true
}
return false
}
}
上述的運算符函數(shù)實現(xiàn)了“相等”運算符间唉,來判斷兩個Coordinate類型是否相等,對于Coordinate類型而言利术,相等表示兩個屬性“x”和“y”相等呈野;“不等”運算符表示只要Coordinate只要有一個屬性不相等,即可判斷為兩個Coordinate類型不相等印叁。
let point = Coordinate(x: 1.0, y: 1.0)
let anotherPoint = Coordinate(x: 2.0, y: 2.0)
print(point == anotherPoint)
print(point != anotherPoint)
由于point的兩個屬性x被冒、y和anotherPoint的兩個屬性x军掂、y值不相等,因此進行相等(==)運算的結果為false昨悼,進行不等(!=)的運算結果為true蝗锥。
2.5、自定義運算符
除了標準運算符率触,Swift還可以聲明和實現(xiàn)自定義運算符终议。
自定義運算符需要在全局作用域通過關鍵字operator進行定義,同時要指定prefix(前綴)葱蝗、infix(中綴)或postfix(后綴)修飾符:
prefix operator +++
上面的代碼定義了一個名為+++的前綴運算符穴张。在Swift中+++并沒有實際的意義,我們可以通過Coordinate實例來定義它的意義垒玲。對于Coordinate類型來講陆馁,可以將+++定義為雙自增前綴運算符找颓,實現(xiàn)Coordinate對自身的相加合愈。
extension Coordinate {
static prefix func +++(coordinate: inout Coordinate) -> Coordinate {
coordinate += coordinate
return coordinate
}
}
上述中的運算符函數(shù)通過自定義的加法賦值運算符讓Coordinate實現(xiàn)自身的相加。
var point = Coordinate(x: 1.0, y: 6.0)
let anotherPoint = +++point
由于+++運算符實現(xiàn)對自身相加击狮,并輸出一個Coordinate實例佛析,因此上述例子中point的值最終的結果為(2.0,12.0)彪蓬,anotherPoint的值為(2.0寸莫,12.0)。