作者:花都色魔l文龙l_419 | 来源:互联网 | 2023-06-27 19:14
IamtryingtoextendmyprotocolOptionwithComparabletousesimple.sort()method.我正在尝试使用Compar
I am trying to extend my protocol Option
with Comparable
to use simple .sort()
method.
我正在尝试使用Comparable扩展我的协议选项以使用简单的.sort()方法。
Below short example only with Equatable
to show errors.
以下简短示例仅使用Equatable来显示错误。
@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
}
The Option
protocol must be marked as @objc
or inherit from NSObjectProtocol
because it will be used with UIKit
.
Option协议必须标记为@objc或从NSObjectProtocol继承,因为它将与UIKit一起使用。
Errors:
-
@objc protocol 'Option' cannot refine non-@objc protocol 'Equatable'
@objc协议'选项'无法优化非@objc协议'Equatable'
-
Protocol 'Option' can only be used as a generic constraint because it has Self or associated type requirements
协议'选项'只能用作通用约束,因为它具有自我或相关类型要求
Do you have any suggestion how to solve this problem?
你有什么建议如何解决这个问题?
2 个解决方案
4
Equatable
lives in the Swift world only, thus you cannot extend it to a protocol that will be used by Objective-C. Trying to do this results in error #1
只能在Swift世界中生活,因此您无法将其扩展为Objective-C将使用的协议。尝试这样做会导致错误#1
Protocols that have a Self
requirement (i.e. at least one method from the protocol declaration contains Self
) cannot be used as arguments to functions, or to variable declarations, only as arguments to a generic clause, e.g. func doSomething(argument: T)
.
具有Self要求的协议(即,协议声明中的至少一个方法包含Self)不能用作函数或变量声明的参数,仅作为泛型子句的参数,例如, func doSomething
(参数:T)。
Removing Equatable
from the Option
protocol declaration, and declaring ==
as generic on Option
will solve the compile errors. As for sorting, you can also overload the <
operator, and sort via that operator (without needing to implement Comparable
):
从Option协议声明中删除Equatable,并在Option上声明== as generic将解决编译错误。至于排序,你也可以重载 <运算符,并通过该运算符排序(无需实现comparable):
@objc protocol Option {
var title: String { get }
var enabled: Bool { get }
var position: Int { get }
}
func ==(lhs: T, rhs: T) -> Bool {
return lhs.position == rhs.position
}
func <(lhs: T, rhs: T) -> Bool {
return lhs.position
This allows you to pass objects that conform to the protocol to UIKit
, and to also compare them within your swift code.
这允许您将符合协议的对象传递给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
One important note regarding the sorting code above: if you don't specify the type for c
, then the compiler infers its type as [NSObject]
, and the sort
call will not compile due to ambiguity of the <
operator. You need to explicitly declare c
as [Option]
to take advantage of the overloaded operator.
关于上面的排序代码的一个重要注意事项:如果你没有为c指定类型,那么编译器会将其类型推断为[NSObject],并且由于 <运算符的模糊性,排序调用将无法编译。您需要将c显式声明为[option]以利用重载运算符。