我正在尝试使用Comparable扩展我的协议选项以使用简单的.sort()方法.
@objc protocol Option: Equatable { var title: String { get } var enabled: Bool { get } var position: Int { get } } func ==(lhs: Option,rhs: Option) -> Bool { return lhs.position == rhs.position }
Option协议必须标记为@objc或从NSObjectProtocol继承,因为它将与UIKit一起使用.
错误:
>
@objc protocol ‘Option’ cannot refine non-@objc protocol
‘Equatable’
>
Protocol ‘Option’ can only be used as a generic constraint
because it has Self or associated type requirements
你有什么建议如何解决这个问题?
解决方法
只能在Swift世界中生活,因此您无法将其扩展到Objective-C将使用的协议.尝试这样做会导致错误#1
具有Self要求的协议(即,协议声明中的至少一个方法包含Self)不能用作函数或变量声明的参数,仅作为泛型子句的参数,例如,func doSomething< T:Option>(参数:T).
从Option协议声明中删除Equatable,并在Option上声明== as generic将解决编译错误.至于排序,你也可以重载<运算符,并通过该运算符排序(无需实现Comparable):
@objc protocol Option { var title: String { get } var enabled: Bool { get } var position: Int { get } } func ==<T: Option>(lhs: T,rhs: T) -> Bool { return lhs.position == rhs.position } func <<T: Option>(lhs: T,rhs: T) -> Bool { return lhs.position < rhs.position }
这允许您将符合协议的对象传递给UIKit,并在快速代码中对它们进行比较.
class A: NSObject,Option { .. } class B: NSObject,Option { ... } let a = A() let b = B() a == b // compiles,and returns true if a and b have the same position let c: [Option] = [a,b] c.sort(<) // returns a sorted array by the `position` field
关于上面的排序代码的一个重要注意事项:如果你没有为c指定类型,那么编译器会将其类型推断为[NSObject],并且由于<的不明确性,排序调用将无法编译.操作符.您需要将c显式声明为[Option]以利用重载运算符.