Родовой тип RawRepresentable неверно интерпретируется как self

Использовать NSCoding с типом Enum Свифта я сделал расширение на NSCoder:

extension NSCoder {
    func encodeEnum<Enum: RawRepresentable where Enum.RawValue == String>(value: Enum, forKey key: String) {
        self.encodeObject(value.rawValue, forKey: key)
    }

    func decodeEnumForKey<Enum: RawRepresentable where Enum.RawValue == String>(key: String) -> Enum? {
        guard let returnValue = self.decodeObjectForKey(key) as? String else { return nil }
        return Enum(rawValue: returnValue)
    }
}

encodeEnum Метод отлично работает для StringEnum, но когда я пытаюсь декодировать предыдущий Enum, вот так:

enum MyEnum: String { case Something, Other }
class MyEnumClass: NSObject, NSCoding {
    let myEnum: MyEnum

    init(myEnum: MyEnum) {
        self.myEnum = myEnum
    }

    required convenience init?(coder aDecoder: NSCoder) {
        guard let tmp = aDecoder.decodeEnumForKey("myKey") as? MyEnum else { return nil }

        self.init(myEnum: tmp)
    }
}

Я получаю сообщение об ошибке aDecoder.decodeEnumForKey("myKey"):

Value of type `NSCoder` has no member `RawValue`

Я уверен, что это как-то связано с общим и условием, что Enum.RawValue == String, Но я не понимаю, пока он не работает, но работает на encodeEnum(),

1 ответ

Решение

Проблема в том, что в

guard let tmp = aDecoder.decodeEnumForKey("myKey") as? MyEnum else { return nil }

компилятор не может определить общий заполнитель

func decodeEnumForKey<Enum: ...>(key: String) -> Enum?

быть MyEnum, вы должны привести результат к MyEnum? вместо:

guard let tmp = aDecoder.decodeEnumForKey("myKey") as MyEnum? else { return nil }

так что возвращаемый тип выводится как MyEnum? из вызывающего контекста.

Другие вопросы по тегам