我正在尝试为表单中的字段提供模型。有一个父“Field”类,具有该类型的泛型,然后是不同类型字段的子类。这是主要的Field类及其相关协议:
protocol FieldProtocol {
var stringRepresentation: String { get }
}
class Field<T>: FieldProtocol {
var value: T
var stringRepresentation: String {
return "\(value)"
}
required init(value: T) {
self.value = value
}
}
然后我有一个子类,它是一个文本字段:
class TextField: Field<String> {
required init(value: String) {
super.init(value: value)
}
}
另外,我想要一个可以使用任何枚举作为字段的字段,只要枚举符合某个协议:
protocol EnumProtocol {
var rawValue: String { get }
static func getValueFromString(value: String) -> EnumProtocol
}
class EnumField<T: EnumProtocol>: Field<T> {
override var stringRepresentation: String {
return value.rawValue
}
required init(value: T) {
super.init(value: value)
}
}
到目前为止一切顺利。我开始定义符合该协议的枚举,并设置我的字段:
enum AppleType: String, EnumProtocol {
case RedDelicious = "red"
case Honeycrisp = "honeycrisp"
static func getValueFromString(value: String) -> EnumProtocol {
if value == "red" {
return AppleType.RedDelicious
} else {
return AppleType.Honeycrisp
}
}
}
let nameField = TextField(value: "Will Clarke")
var appleField = EnumField<AppleType>(value: .RedDelicious)
这一切都按预期工作。我有一个TextField对象和一个EnumField对象。
在我的主要表单中,我有一个包含该表单上所有字段的数组。我想循环遍历它们并根据它们的实际类型做一些不同的事情。
var fieldArray: [FieldProtocol] = [appleField, nameField]
for field in fieldArray {
if let validField = field as? TextField {
print(validField.value)
} else if let validField = field as? WHAT GOES HERE??? {
print(validField.value.rawValue)
}
}
显然,我的问题是放在“什么东西在这里?”从语义上讲,我想要的是“使用任何符合EnumField的对象的EnumField”,我认为它是“EnumField”。但这不起作用。
我尝试过“EnumField”,但Xcode抱怨说“'EnumField?'不符合协议'EnumField'“。
必须有办法做到这一点......对吗?
你可以把所有代码都放到Playground中 - 除了相关的行之外,它应该全部工作。