Перечень структур в 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'

Я предполагаю, что перечисления не могут быть использованы таким образом. Мы должны использовать примитивы.

5 ответов

Так должно быть:

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 и enum, названный как MyEnum,

На самом деле, я не совсем уверен в необходимости CustomStruct быть родителем MyEnum достичь того, что вы пытаетесь; Как упомянуто выше во фрагментах, вы можете вернуть экземпляр структуры, основываясь на значении указанного перечисления.

Я не комментирую выбор использования перечисления здесь, а просто объясняю, почему вы получили эту ошибку и как объявить перечисление, в котором пользовательский объект является родительским.

Ошибка показывает вам проблему, 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 и TWO,должны быть представлены с литералом Swift, проверьте в этом посте Swift 2 список доступных литералов (int,string,array,dictionary и т. Д.). Но учтите, что в Swift 3 протоколы LiteralConvertible теперь называются ExpressibleByXLiteral после переименования Big Swift.
  2. Требование к реализацииRawRepresentableпокрывается реализацией одного из экспрессируемых протоколов (init?(rawValue:)будет использовать инициализатор, который мы написали для поддержки литералов).
  3. Перечисления также должны быть Equatable, поэтому вам придется реализовать оператор равенства для вашего CustomStruct базовый тип.

Согласно документации:

Если значение (известное как "необработанное" значение) предоставляется для каждого случая перечисления, это может быть строка, символ или значение любого целочисленного типа или типа с плавающей запятой.

Так что да, вы не можете установить тип структуры в качестве исходного значения enum.

В вашем случае я бы предложил использовать string в качестве необработанного значения enum и некоторого словаря, отображающего эти строки в CUSTOM_STRUCT тип.

Вы пытались соответствовать RawRepresentable, как спрашивает ошибка?

Использование представления JSON должно работать для переменных1 и переменных3. Для переменной2 может потребоваться дополнительная работа.

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

A bit late on the party but maybe useful for someone else. I would consider to simply use computed variables instead of a struct.

      enum MyEnum {
    case getData
    case addNewData

    var variable1: String {
        switch self {
            case .getData: return "data1"
            case .addNewData: return "data2"
        }
    }
    
    var variable2: Int {
        switch self {
            case .getData: return 1
            case .addNewData: return 2
        }
    }
    
    // ....
}

Usage:

      let data = MyEnum.getData

print (data.variable1) // "data1"
Другие вопросы по тегам