我正在編寫a library,它爲默認的Swift類型創建擴展。檢查一個類型是否實現協議
我想檢查我的Array擴展是否某個類型實現了某個協議。例如看到這個方法:
extension Array {
/// Compares the items using the given comparer and only returns non-equal values
/// :returns: the first items that are unique according to the comparer
func distinct(comparer: (T, T) -> Bool) -> [T] {
var result: [T] = []
outerLoop: for item in self {
for resultItem in result {
if comparer(item, resultItem) {
continue outerLoop
}
}
result.append(item)
}
return result
}
}
現在,我想改寫這個方法來檢查,如果T
是Equatable
這樣:
/// Compares the items using the given comparer and only returns non-equal values
/// :returns: the first items that are unique according to the comparer
func distinct(comparer: ((T, T) -> Bool)?) -> [T] {
var result: [T] = []
outerLoop: for item in self {
for resultItem in result {
if isEquatable ? comparer!(item, resultItem) : item == resultItem {
continue outerLoop
}
}
result.append(item)
}
return result
}
其中isEquatable
是Bool
值,它告訴我,如果T
是Equatable
。我怎樣才能找到這個?
'我猜你的目標是調用者可以跳過提供比較函數,所以它會回落到Equatable(如果可用)?'是的,但只有當'T'不是'Equatable'且給定閉包是'nil'時纔會崩潰。我將在明天某處查看此代碼,並接受適用的代碼。 – vrwim
有沒有辦法在擴展中做到這一點?我不想膨脹我的全球範圍......特別是因爲這是一個圖書館。 – vrwim
你可以創建一個'Collections Collections {static func distinct etc ...}',然後用'Collections.distinct([1,2,3])'調用它,但要記住Swift已經隱含了框架名稱空間(例如,如果你正在編寫一個框架「CoolStuff」,那麼這個函數將是'CoolStuff.distinct'。這就是Swift庫的功能,即'filter'實際上是'Swift.filter'(但是所有的Swift項目隱含'import Swift') –