作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
嘿,我正在尝试构建一个基类来执行某些在应用程序中重复的操作,但我遇到了一个我无法真正理解的问题,以下代码举例说明了我正在尝试的操作构建:
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
符合这些协议(protocol)。
最佳答案
问题是,当你在协议(protocol)定义中声明具体类型要求时,你不能使用子类(或者如果声明的类型要求是协议(protocol)类型,则符合协议(protocol)的类型),你需要使用实际的(协议(protocol)) 输入一致的类。
这是您看到的继承行为。您不能通过使属性的类型成为父类(super class)中声明的类型的子类来覆盖继承的属性。当使用父类(super class)类型/协议(protocol)类型来表示子类/符合类时,这会导致意外行为。
您可以通过使用关联类型使您的协议(protocol)通用来解决这个问题。
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] = []
}
关于Swift 类不符合带有枚举的协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53209077/
我是一名优秀的程序员,十分优秀!