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
不符合 GenericModel
且 ExampleVM
不符合 GenericVM
。
解决这个问题的方法是使用GenericRow
、GenericSection
和GenericModel
,我的问题是为什么我不能使用相应的Row
、Section
和 Model
符合这些协议。
您使用协议类型本身声明了您的 GenericModel
/GenericVM
,而不是实现您的 GenericSection
/GenericRow
协议的类型。
要使您的代码正常工作,您需要使用 associatedtype
s:
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] = []
}
嗨,我正在尝试构建一个基础 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
不符合 GenericModel
且 ExampleVM
不符合 GenericVM
。
解决这个问题的方法是使用GenericRow
、GenericSection
和GenericModel
,我的问题是为什么我不能使用相应的Row
、Section
和 Model
符合这些协议。
您使用协议类型本身声明了您的 GenericModel
/GenericVM
,而不是实现您的 GenericSection
/GenericRow
协议的类型。
要使您的代码正常工作,您需要使用 associatedtype
s:
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] = []
}