2016-05-20 11 views
3

プロトコルで列挙型を定義する必要はありますか?Swiftプロトコルで列挙型を定義する方法を教えてください

//trying to do this 
protocol JSONEncodable { 
    enum PropertyName // Type not allowed here 
    func valueForProperty(propertyName:PropertyName) -> Any 
} 

//which would be implemented like this 
struct Person : JSONEncodable { 
    var firstName : String 
    var lastName : String 

    enum PropertyName { 
     case FirstName 
     case LastName 
     func allValues() { 
      return [Person.PropertyName.FirstName, Person.PropertyName.LastName] 
     } 
     func stringValue() { 
      return "\(self)" 
     } 
    } 
    func valueForProperty(propertyName:PropertyName) -> Any { 
     switch propertyName { 

     case .FirstName: 
      return firstName 

     case .LastName: 
      return lastName 
     } 
    } 
} 

//so that I could do something like this 
extension JSONEncodable { 

    func JSONObject() -> [String:AnyObject] { 
     var dictionary = [String:AnyObject]() 
     for propertyName in PropertyName.allValues { 
      let value = valueForProperty(propertyName) 

      if let valueObject = value as? AnyObject { 
       dictionary[propertyName.stringValue()] = valueObject 

      }else if let valueObject = value as? JSONEncodable { 
       dictionary[propertyName.stringValue()] = valueObject.JSONObject() 
      } 

     } 
     return dictionary 
    } 
} 
+0

に付着しなければならないあなたのユースケースとは何ですか? – JAL

+0

なぜこれが欲しいですか?あなたは何を達成しようとしていますか? – Alexander

答えて

3

これはSwiftでは不可能です。可能であれば、どのようなケースを参照することはできないので(それが何であるか分からないため)、直接使用する方法は不明です。あなたは最終的にasキャストしなければならないでしょう、それはプロトコルの全ポイントを壊す。 (一つはenumは、コレクション型だったが、それはありません、それがなかった場合は、ちょうど必要とすることができれば使用して想像の「コレクション型を。」)

6

プロトコルだけで任意のサブクラスでに付着する必要があろうassociatedtypesを持つことができます:

enum MyEnum { 
    case foo 
    case bar 
} 

protocol RequiresEnum { 
    associatedtype SomeEnumType 

    func doSomethingWithEnum(someEnumType: SomeEnumType) 
} 

class MyRequiresEnum: RequiresEnum { 
    typealias SomeEnumType = MyEnum 

    func doSomethingWithEnum(someEnumType: SomeEnumType) { 
     switch someEnumType { 
     case .foo: 
      print("foo") 
     case .bar: 
      print("bar") 
     } 
    } 
} 

let mre = MyRequiresEnum() 
mre.doSomethingWithEnum(.bar) 

編集:associatedtype

関連する問題