我正在编写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') –