2014-11-04 17 views
4

今天我正在閱讀有關異或交換的內容,並且認爲我會嘗試在Swift中實現一個可以執行此操作的函數。我成功地寫了這個功能的非通用版本:Swift中的通用異或交換

import UIKit 

func xorSwap (inout x: Int, inout y: Int) { 
    if x != y { 
     x ^= y 
     y ^= x 
     x ^= y 
    } 
} 


var a = 10 
var b = 20 

xorSwap(&a, &b) 

println(a) //=> 20 
println(b) //=> 10 

然後我試着寫的這一個通用版本,但編譯器抱怨說,「T不等同於布爾」。我假設有另一個協議我需要聲明一致性,但我不確定那是什麼。這裏的嘗試在一個通用版本:

import UIKit 

func xorSwap<T: Equatable> (inout x: T, inout y: T) { 
    if x != y { 
     x ^= y 
     y ^= x 
     x ^= y 
    } 
} 


var a = 10 
var b = 20 

xorSwap(&a, &b) 

println(a) 
println(b) 

有沒有人有更好的理解這一點,可以幫我填我的理解的差距?謝謝。

+0

認真 - 不要打擾,除非它只是對於閒置的好奇心 - XOR交換隻是一個噱頭,並不是特別有用或有效。 – 2014-11-04 16:19:18

+2

哦,是的,我應該澄清,這只是一個好奇心。我沒有看到我自己在任何地方使用它,但我的好奇心越來越好。 – mike 2014-11-04 16:31:19

+1

唷,這是一種解脫。 ;-) – 2014-11-04 16:31:42

回答

5

您可以使用內置的BitwiseOperationsType

func xorSwap<T: protocol<BitwiseOperationsType, Equatable>> (inout x: T, inout y: T) { 
    if x != y { 
     x ^= y 
     y ^= x 
     x ^= y 
    } 
} 

var a = 10 
var b = 20 

xorSwap(&a, &b) 

println(a) // -> 20 
println(b) // -> 10 

var a = NSStringCompareOptions.CaseInsensitiveSearch 
var b = NSStringCompareOptions.BackwardsSearch 

xorSwap(&a, &b) 

a == .BackwardsSearch // -> true 
b == .CaseInsensitiveSearch // -> true 
+0

另一種語法是func xorSwap (inout x:T,inout y:T) – vbezhenar 2014-11-04 16:46:35

+0

這就是我正在尋找的。謝謝!一個問題雖然在語法上:協議聲明類型必須符合BitwiseOperationsType和Equatable?我假設你可以聲明用逗號分隔的協議,但編譯器不喜歡這樣做。 – mike 2014-11-04 16:51:26

+1

它被稱爲「協議組成」,參見:https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-XID_424 – rintaro 2014-11-04 16:52:28

0

您的函數對其參數執行兩種操作:!=和xor。

您指定的類型約束條件只能保證T必須是Equatable,它隱含地爲您提供!=

您必須添加,保證約束XOR:

// protocol that guarantees^operator 
protocol Xorable { 
    func ^(lhs: Self, rhs: Self) -> Self 
} 

// declare Int to support xor 
extension Int : Xorable {} 

// Your slightly modified function that depends on xor and Equatable 
func xorSwap<T : protocol<Xorable, Equatable>> (inout x: T, inout y: T) { 
    if x != y { 
     x = x^y 
     y = y^x 
     x = x^y 
    } 
}