2016-12-13 1 views
2

J'ai une méthode qui appelle la méthode de certains gestionnaires pour enregistrer la valeur int avec une clé. Ma méthode reçoit int et une EnumKey valeur ENUM comme une clé, extrude rawValue de EnumKey et il passe à un gestionnaire comme une chaîne:Comment faire un protocole décrivant des énumérations représentables par des chaînes?

set(value: Int, forKey key: EnumKey) { 
    SomeManager.saveIntValueWithStringKey(valueToSave: value, keyToSave: key.rawValue) 
} 

enum EnumKey: String { 
    case One="first key" 
    case Two="second key" 
} 

Je veux rendre plus générique allow ma méthode pour recevoir tous les ENUM avec chaîne valeur brute au lieu de EnumKey. Dans la mise en œuvre de la méthode que j'ai remplacé le type de paramètre clé de EnumKey à GenericKey protocole, et fait EnumKey conforme ce protocole:

set(value: Int, forKey key: GenericKey) { 
    SomeManager.saveIntValueWithStringKey(valueToSave: value, keyToSave: key.rawValue) 
} 

protocol GenericKey { 
    var rawValue: String { get } 
} 

enum EnumKey: String, GenericKey { 
    case One="first key" 
    case Two="second key" 
} 

Mais ce String, GenericKey ressemble un peu laid. Je veux que chaque enum représentable par chaîne convienne automatiquement sans mentionner qu'il est conforme au protocole GenericKey en plus de RawRepresentable et String raw type. Quelque chose comme:

protocol GenericKey: RawRepresentable { 
    associatedtype RawValue = String 
} 

mais compilateur dit « protocole peut être utilisé que comme une contrainte générique parce qu'il a auto ou des exigences de type associés ».

Ce qui pourrait être un moyen facile d'expliquer le compilateur que le protocole décrit seulement les choses RawRepresentable avec RawValue de type String?

Répondre

1

Vous pouvez définir la fonction comme générique et définir le type générique comme RawRepresentable avec RawValue de type String, comme ceci:

class Test { 
    func set<T: RawRepresentable>(value: Int, forKey key: T) where T.RawValue == String { 
     print("value \(value), key: \(key.rawValue)") 
    } 
} 

enum EnumKey: String { 
    case One="first key" 
    case Two="second key" 
} 

let t = Test() 
t.set(value: 3, forKey: EnumKey.One) // prints "value 3, key: first key" 
+0

merci! ça a l'air beaucoup mieux :) – abjurato