我正在尝试使用Option扩展协议(protocol)Comparable以使用简单的.sort()方法。

下面的简短示例仅使用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
}
Option协议(protocol)必须标记为@objc或从NSObjectProtocol继承,因为它将与UIKit一起使用。

错误:

  • 您对如何解决这个问题有什么建议吗?

    最佳答案

    Equatable仅存在于Swift世界中,因此您不能将其扩展到由Objective-C使用的协议(protocol)。尝试执行此操作将导致错误#1

    Self要求的协议(protocol)(即协议(protocol)声明中至少有一种方法包含Self)不能用作函数或变量声明的参数,而只能用作通用子句的参数,例如func doSomething<T: Option>(argument: T)

    Equatable协议(protocol)声明中删除Option,并在==上将Option声明为通用将解决编译错误。至于排序,您还可以重载<运算符,并通过该运算符进行排序(无需实现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
    }
    

    这使您可以将符合协议(protocol)的对象传递给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],并且由于sort运算符的歧义,因此不会编译<调用。您需要将c明确声明为[Option]才能利用重载的运算符。

    关于ios - 在Swift中使用Comparable扩展@objc协议(protocol),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34787721/

    10-13 09:33