0

我需要从 REST API 获取一些对象并使用 ObjectMapper 将它们映射到本地对象。

这些对象包含许多枚举。它们都以整数形式出现,我想将它们映射到本地描述的枚举。

为此,我必须描述 ObjectMapper 使用的标准转换函数。

    enum Types: Int {
        case Uno  = 1
        case Dos  = 2
        case Tres = 3

        static var transform = TransformOf<Types,Int>(
            fromJSON: {
                $0 != nil
                ? Types(rawValue:$0!)
                : nil
            },
            toJSON: { $0?.rawValue})
    }

问题是我有许多这样的枚举,并且函数在所有枚举中都是完全相同的,除了TransformOf<..>列表中的第一个参数是特定于每个枚举的。

我想要做的是创建一个具有该功能的默认实现的通用协议,例如

protocol Transformable {
var transform: TransformOf<self.Type,Int> {
    get {
        return TransformOf<self.Type,Int>(
                    fromJSON: {
                        $0 != nil
                        ? Types(rawValue:$0!)
                        : nil
                    },
                    toJSON: { $0?.rawValue})
        }
    }
}

...然后将具有实现的协议应用于我拥有的所有枚举。

显然 reference ofself.Type在那里不起作用,我只是不知道如何一般地引用最终将使用该函数的特定实例的类型?可能我在想解决这个问题的错误方法。

4

1 回答 1

1

我认为您缺少的是Self标识符。在实现泛型时,Self关键字充当实现协议的类型的占位符。(欲了解更多信息

换句话说:

protocol Transformable {
    var rawValue: Int { get }
    init?(rawValue: Int)
    func toJSON() -> Int
    static func fromJSON(rawValue: Int) -> Self?
}

然后,每个enum符合协议的Transformable都会有一个返回自己类型的静态方法。

其次,由于这是 Swift 2,您可以实现协议扩展:

extension Transformable {
    func toJSON() -> Int {
        return self.rawValue
    }

    static func fromJSON(rawValue: Int) -> Self? {
        return Self(rawValue: rawValue)
    }
}

现在所有符合协议的枚举都将自己转换为Int

enum Types: Int, Transformable {
    case Uno = 1
    case Dos = 2
    case Tres = 3
    //No extra implementation
}

enum OtherTypes: Int, Transformable {
    case Cuatro = 4
    case Cinco = 5
    case Seis = 6
    //No extra implementation
}

print(Types.fromJSON(1)!) //prints Uno
print(OtherTypes.fromJSON(4)!) //prints Cuatro
print(Types.fromJSON(4)!) /* throws an error, because the Types enum
                             does not recognise 4 as a raw value */
于 2015-12-19T14:44:31.300 回答