在 Swift 中的协议类型数组上使用 index(of:)

Use index(of:) on Array of Protocol Type in Swift

为了在我的大部分静态 tableView 中增加更多的灵活性,我有一个这样定义的协议:

protocol StaticSection {
    static var active: [StaticSection] { get }
    // func cell(forRowAt indexPath: IndexPath, tableView: UITableView) -> UITableViewCell
    // var numberOfRows: Int { get }
}

extension StaticSection: Equatable {
    static func at(_ index: Int) -> StaticSection {
        return active[index]
    }

    static func index(ofSection section: StaticSection) -> Int {
        return active.index(of: section) // Not working :(
    }
}

我是这样用的

enum MySections: StaticSection {
    case header, footer, sectionA, sectionB

    static var active: [StaticSection] {
        // Here I can dynamically enable/disable/rearrange sections
        return [MySections.header, .footer]
    }
}

在协议的 enum 实现中,我可以像这样访问一个部分的索引:

(StaticSections.active as! [MySections]).index(of: .header)

现在我想在扩展中实现 index(ofSection section: StaticSection) 以便有更方便的方法来执行此操作。 我试过了,就像上面扩展中显示的那样。但我收到错误:

Cannot invoke 'index' with an argument list of type '(of: StaticSection)'

这在 Swift 中甚至可能吗?

你可以这样做:

protocol StaticSection {
    static var active: [Self] { get } // note the change to Self
    // func cell(forRowAt indexPath: IndexPath, tableView: UITableView) -> UITableViewCell
    // var numberOfRows: Int { get }
}

extension StaticSection where Self : Equatable { // another change here
    static func at(_ index: Int) -> Self {
        return active[index]
    }

    static func index(ofSection section: Self) -> Int? {
        return active.index(of: section)
    }
}

enum MySections: StaticSection {
    case header, footer, sectionA, sectionB

    static var active: [MySections] { // note the change to MySections
        // Here I can dynamically enable/disable/rearrange sections
        return [.header, .footer]
    }
}

这里要注意的重要一点是这个语法:

where Self : Equatable

这意味着扩展仅适用于符合 StaticSectionEquatable 的类型,而这:

: Equatable

将使 StaticSection 继承自 Equatable,这在 Swift.

中是做不到的