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})
        }
    }
}

...そして、実装を含むプロトコルを私が持っているすべての列挙に適用します。

明らかに参照がself.Typeそこで機能していません。最終的に関数を使用する特定のインスタンスのタイプを一般的に参照する方法がわかりませんか? おそらく私はその問題を解決する間違った方法を考えています。

4

1 に答える 1

1

あなたが見逃しているのはSelf識別子だと思います。Generics を実装する場合、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 に答える