web-dev-qa-db-ja.com

Swift 3.0の構造体の列挙型

初期化したい構造体の列挙型を作成しようとしています:

struct CustomStruct {
    var variable1: String
    var variable2: AnyClass
    var variable3: Int

    init (variable1: String, variable2: AnyClass, variable3: Int) {
        self.variable1 = variable1
        self.variable2 = variable2
        self.variable3 = variable3
    }
}

enum AllStructs: CustomStruct {
    case getData
    case addNewData

    func getAPI() -> CustomStruct {
        switch self {
            case getData:
                return CustomStruct(variable1:"data1", variable2: SomeObject.class, variable3: POST)

            case addNewData:
                // Same to same

            default:
                return nil
        }
    }
}

次のエラーが発生します。

タイプAllStructsがプロトコル「RawRepresentable」に準拠していません

列挙型はこのように使用できないと思います。プリミティブを使用する必要があります。

10
Siddharth

そのはず:

struct CustomStruct {
    var apiUrl: String
    var responseType: AnyObject
    var httpType: Int

    init (variable1: String, variable2: AnyObject, variable3: Int) {
        self.apiUrl = variable1
        self.responseType = variable2
        self.httpType = variable3
    }
}

enum MyEnum {
    case getData
    case addNewData

    func getAPI() -> CustomStruct {
        switch self {
        case .getData:
            return CustomStruct(variable1: "URL_TO_GET_DATA", variable2: 11 as AnyObject, variable3: 101)
        case .addNewData:
            return CustomStruct(variable1: "URL_TO_ADD_NEW_DATA", variable2: 12 as AnyObject, variable3: 102)
        }
    }
}

使用法:

let data = MyEnum.getData
let myObject = data.getAPI()

// this should logs: "URL_TO_GET_DATA 11 101"
print(myObject.apiUrl, myObject.responseType, myObject.httpType)

命名規則では、構造体の名前はCustomStruct、列挙型の名前はMyEnumであることに注意してください。

実際、あなたがやろうとしていることを達成するために、CustomStructMyEnumの親にする必要があるかどうかはよくわかりません。上記のスニペットで述べたように、参照された列挙型の値に基づいて構造体のインスタンスを返すことができます。

15
Ahmad F

ここでは列挙型を使用する選択についてコメントしていませんが、エラーが発生した理由と親としてカスタムオブジェクトを持つ列挙型を宣言する方法について説明しています。

エラーは問題を示しています。CustomStructは、その列挙型の基本クラスとして使用するために RawRepresentable を実装する必要があります。

これはあなたがする必要があることをあなたに示す簡単な例です:

_struct CustomStruct : ExpressibleByIntegerLiteral, Equatable {
    var rawValue: Int = 0

    init(integerLiteral value: Int){
        self.rawValue = value
    }

    static func == (lhs: CustomStruct, rhs: CustomStruct) -> Bool {
        return
            lhs.rawValue == rhs.rawValue
    }
}


enum AllStructs: CustomStruct {
    case ONE = 1
    case TWO = 2
}
_

このスニペットで確認できるいくつかの重要な点:

  1. ONEやTWOmustのような場合は、Swiftliteralで表すことができます。チェック thisSwift2 post 使用可能なリテラル(int、string、array、dictionaryなど)のリスト。ただし、Swift3では、LiteralConvertibleプロトコルがビッグSwiftの名前変更後にExpressibleByXLiteralと呼ばれるようになっていることに注意してください。
  2. RawRepresentableを実装するための要件は、Expressibleプロトコルの1つを実装することでカバーされています(init?(rawValue:)は、リテラルをサポートするために作成した初期化子を利用します)。
  3. 列挙型mustEquatableである必要があるため、CustomStruct基本型に等式演算子を実装する必要があります。
13

エラーが要求しているように、RawRepresentableに準拠しようとしましたか?

JSON表現の使用は、variable1とvariable3で機能するはずです。 variable2には、追加の作業が必要になる場合があります。

struct CustomStruct: RawRepresentable {
    var variable1: String
    var variable2: AnyClass
    var variable3: Int
    init?(rawValue: String) {
        guard let data = rawValue.data(using: .utf8) else {
            return nil
        }
        guard let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
            return nil
        }
        self.variable1 = (json["variable1"] as? String) ?? ""
        self.variable2 = (json["variable2"] as? AnyClass) ?? AnyClass()
        self.variable3 = (json["variable3"] as? Int) ?? 0
    }
    var rawValue: String {
        let json = ["variable1": self.variable1,
                    "variable2": self.variable2,
                    "variable3": self.variable3
                    ]
        guard let data = try? JSONSerialization.data(withJSONObject: json, options: []) else {
            return ""
        }
        return String(data: data, encoding: .utf8) ?? ""
    }
}
3
Cœur

ドキュメント によると:

値(「生の」値として知られている)が各列挙ケースに提供されている場合、値は文字列、文字、または値になります。任意の整数型または浮動小数点型の。

そうです、構造体タイプを列挙型の生の値に設定することはできません。

あなたの場合、列挙型の生の値としてstringを使用し、これらの文字列をCUSTOM_STRUCTタイプにマッピングする辞書を使用することをお勧めします。

2
Vadim Popov