首页 > 解决方案 > 在 Swift 中的协议类型数组上使用 index(of:)

问题描述

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

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)在扩展中实现,以便有一种更方便的方式来做到这一点。我尝试了如上面扩展中所示的那样。但我得到了错误:

无法使用类型为“(的:StaticSection)”的参数列表调用“索引”

这在 Swift 中是否可行?

标签: swiftgenericsswift-protocols

解决方案


你可以这样做:

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

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

: Equatable

将使StaticSection继承自Equatable,这是您在 Swift 中无法做到的。


推荐阅读