如何得到一个快速枚举的关联值,无论枚举的情况下

我有一个对象FormField,它有两个属性:一个stringname和一个value可以接受任何types – 因此,我已经把它Any! 。 然而,我已经被告知在一个单独的问题使用枚举与关联的值而不是Any!

 enum Value { case Text(String!) case CoreDataObject(NSManagedObject!) } class FormField { var name: String var value: Value? // initializers... } 

然而,这种方法使得检查无效性非常冗长。 如果我想要显示窗体中所有缺less的字段的警报视图,我将不得不在switch语句中对每个案例重复检查:

 for field in self.fields { if let value = field.value { switch value { case .Text(let text): if text == nil { missingFields.append(field.name) } case .CoreDataObject(let object): if object == nil { missingFields.append(field.name) } } } } 

是否有一个更短的方式访问枚举的关联值,不pipetypes? 如果我使FormField.value Any! 上面的代码将如下所示:

 for field in self.fields { if field.value == nil { missingFields.append(field.name) } } 

enum定义一个方法isMissing() – 只写一次。 那么你几乎可以得到你喜欢的东西:

 for field in self.fields { if field.value.isMissing() { missingFields.append(field.name) } } 

它看起来像这样(来自Swift Interpreter):

  1> class Foo {} > 2> enum Value { 3. case One(Foo!) 4. case Two(Foo!) 5. 6. func isMissing () -> Bool { 7. switch self { 8. case let .One(foo): return foo == nil 9. case let .Two(foo): return foo == nil 10. } 11. } 12. } 13> let aVal = Value.One(nil) aVal: Value = One { One = nil } 14> aVal.isMissing() $R0: Bool = true 

使用Swift 2,可以使用reflection来获取关联的值。

为了简单起见,只需将下面的代码添加到项目中,并使用与EVAssociated协议来扩展枚举。

  public protocol EVAssociated { } public extension EVAssociated { public var associated: (label:String, value: Any?) { get { let mirror = Mirror(reflecting: self) if let associated = mirror.children.first { return (associated.label!, associated.value) } print("WARNING: Enum option of \(self) does not have an associated value") return ("\(self)", nil) } } } 

然后你可以像这样的代码访问.asociated的值:

  class EVReflectionTests: XCTestCase { func testEnumAssociatedValues() { let parameters:[EVAssociated] = [usersParameters.number(19), usersParameters.authors_only(false)] let y = WordPressRequestConvertible.MeLikes("XX", Dictionary(associated: parameters)) // Now just extract the label and associated values from this enum let label = y.associated.label let (token, param) = y.associated.value as! (String, [String:Any]?) XCTAssertEqual("MeLikes", label, "The label of the enum should be MeLikes") XCTAssertEqual("XX", token, "The token associated value of the enum should be XX") XCTAssertEqual(19, param?["number"] as? Int, "The number param associated value of the enum should be 19") XCTAssertEqual(false, param?["authors_only"] as? Bool, "The authors_only param associated value of the enum should be false") print("\(label) = {token = \(token), params = \(param)") } } // See http://github.com/evermeer/EVWordPressAPI for a full functional usage of associated values enum WordPressRequestConvertible: EVAssociated { case Users(String, Dictionary<String, Any>?) case Suggest(String, Dictionary<String, Any>?) case Me(String, Dictionary<String, Any>?) case MeLikes(String, Dictionary<String, Any>?) case Shortcodes(String, Dictionary<String, Any>?) } public enum usersParameters: EVAssociated { case context(String) case http_envelope(Bool) case pretty(Bool) case meta(String) case fields(String) case callback(String) case number(Int) case offset(Int) case order(String) case order_by(String) case authors_only(Bool) case type(String) } 

上面的代码现在可以在https://github.com/evermeer/Stuff#enum上以cocoapod susbspec的forms获得。它还有一个枚举枚举值的枚举扩展。