检查Swift对象是否符合特定协议的通用

时间:2015-10-14 23:54:34

标签: swift generics enums

我正在尝试为表单中的字段提供模型。有一个父“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中 - 除了相关的行之外,它应该全部工作。

0 个答案:

没有答案