J'ai essayé de résumer ce problème à sa forme la plus simple avec ce qui suit.
Installer
Version 6.1.1 de Xcode (6A2008a)
Une énumération définie dans MyEnum.swift:
internal enum MyEnum: Int {
    case Zero = 0, One, Two
}
extension MyEnum {
    init?(string: String) {
        switch string.lowercaseString {
        case "zero": self = .Zero
        case "one": self = .One
        case "two": self = .Two
        default: return nil
        }
    }
}
et le code qui initialise le ENUM dans un autre fichier, MyClass.swift:
internal class MyClass {
    let foo = MyEnum(rawValue: 0)  // Error
    let fooStr = MyEnum(string: "zero")
    func testFunc() {
        let bar = MyEnum(rawValue: 1)  // Error
        let barStr = MyEnum(string: "one")
    }
}
Erreur
Xcode me donne l'erreur suivante lors de la tentative d'initialisation MyEnum avec son initialiseur de valeur brute:
Cannot convert the expression's type '(rawValue: IntegerLiteralConvertible)' to type 'MyEnum?'
Remarques
Par le guide du langage Swift :
Si vous définissez une énumération avec un type à valeur brute, l'énumération reçoit automatiquement un initialiseur qui prend une valeur du type de la valeur brute (en tant que paramètre appelé
rawValue) et renvoie un membre d'énumération ounil.L'initialiseur personnalisé pour a
MyEnumété défini dans une extension pour tester si l'initialiseur de valeur brute de l'énumération a été supprimé en raison du cas suivant de Guide du langage . Cependant, il obtient le même résultat d'erreur.Notez que si vous définissez un initialiseur personnalisé pour un type valeur, vous n'aurez plus accès à l'initialiseur par défaut (ou à l'initialiseur par membre, s'il s'agit d'une structure) pour ce type. [...]
Si vous voulez que votre type de valeur personnalisé soit initialisable avec l'initialiseur par défaut et l'initialiseur par membre, ainsi qu'avec vos propres initialiseurs personnalisés, écrivez vos initialiseurs personnalisés dans une extension plutôt que dans le cadre de l'implémentation d'origine du type de valeur.Le déplacement de la définition d'énumération pour
MyClass.swiftrésoudre l'erreur pourbarmais pas pourfoo.La suppression de l'initialiseur personnalisé résout les deux erreurs.
Une solution de contournement consiste à inclure la fonction suivante dans la définition d'énumération et à l'utiliser à la place de l'initialiseur de valeur brute fourni. Il semble donc que l'ajout d'un initialiseur personnalisé ait un effet similaire au marquage de l'initialiseur à valeur brute
private.init?(raw: Int) { self.init(rawValue: raw) }La déclaration explicite de la conformité du protocole à
RawRepresentabledansMyClass.swiftrésout l'erreur en ligne pourbar, mais entraîne une erreur de l'éditeur de liens concernant les symboles en double (car les énumérations de type à valeur brute sont implicitement conformes àRawRepresentable).extension MyEnum: RawRepresentable {}
Quelqu'un peut-il donner un peu plus d'informations sur ce qui se passe ici? Pourquoi l'initialiseur de valeur brute n'est-il pas accessible?
internalportée (ou au moins correspondre au type), nonprivate.