Swift class 不符合枚举协议

Swift class does not conform to Protocol with Enum

嗨,我正在尝试构建一个基础 class 来执行某些在应用程序中重复的操作,但我遇到了一个我无法真正理解的问题,以下代码举例说明我正在尝试构建的内容:

protocol GenericSection { }
protocol GenericRow { }

protocol GenericModel {
    var section: GenericSection { get }
    var items: [GenericRow] { get }
}

protocol GenericVM {
    var model: [GenericModel] { get set }
}

class ExampleVM: GenericVM {

    enum Row: GenericRow {
        case aRow
    }

    enum Section: GenericSection {
        case aSection
    }

    struct Model: GenericModel {
        let section: Section
        let items: [Row]
    }

    var model: [Model] = []
}

这不会编译,因为 Model 不符合 GenericModelExampleVM 不符合 GenericVM

解决这个问题的方法是使用GenericRowGenericSectionGenericModel,我的问题是为什么我不能使用相应的RowSectionModel 符合这些协议。

您使用协议类型本身声明了您的 GenericModel/GenericVM,而不是实现您的 GenericSection/GenericRow 协议的类型。

要使您的代码正常工作,您需要使用 associatedtypes:

protocol GenericSection { }
protocol GenericRow { }

protocol GenericModel {
    associatedtype SectionType: GenericSection
    associatedtype RowType: GenericRow

    var section: SectionType { get }
    var items: [RowType] { get }
}

protocol GenericVM {
    associatedtype ModelType: GenericModel

    var model: [ModelType] { get set }
}

class ExampleVM: GenericVM {

    enum Row: GenericRow {
        case aRow
    }

    enum Section: GenericSection {
        case aSection
    }

    struct Model: GenericModel {
        let section: Section
        let items: [Row]
    }

    var model: [Model] = []
}

现在它可以工作了,并且知道关于你的具体类型的一切:

let vm = ExampleVM()
vm.model = [.init(section: .aSection, items: [.aRow])]

根据您的协议,这将是使 类 和您创建的结构符合的正确方法:

protocol GenericSection { }
protocol GenericRow { }

protocol GenericModel {
    var section: GenericSection { get }
    var items: [GenericRow] { get }
}

protocol GenericVM {
    var model: [GenericModel] { get set }
}

class ExampleVM: GenericVM {

    var model: [GenericModel] = []

    enum Row: GenericRow {
        case aRow
    }

    enum Section: GenericSection {
        case aSection
    }

    struct Model: GenericModel {
        var section: GenericSection
        var items: [GenericRow]
    }
}

问题是,当您在协议定义中声明具体类型要求时,您不能使用子class(如果声明的类型要求是协议类型,则不能使用符合协议的类型),您需要在符合 class 中使用实际(协议)类型。

这是您看到的继承行为。您不能通过使 属性 的类型成为 superclass 中声明的类型的子class 来覆盖继承的 属性。当使用 superclass type/protocol 类型来表示 subclasses/conforming classes.

时,这会导致意外行为

您可以通过使用关联类型使您的协议通用来解决这个问题。

protocol GenericSection { }
protocol GenericRow { }

protocol GenericModel {
    associatedtype Section:GenericSection
    associatedtype Row: GenericRow

    var section: Section { get }
    var items: [Row] { get }
}

protocol GenericVM {
    associatedtype Model: GenericModel
    var model: [Model] { get set }
}

class ExampleVM: GenericVM {

    enum Row: GenericRow {
        case aRow
    }

    enum Section: GenericSection {
        case aSection
    }

    struct Model: GenericModel {
        let section: Section
        let items: [Row]
    }

    var model: [Model] = []
}