Могу ли я написать протокол, похожий на кодируемый и декодируемый? - PullRequest
0 голосов
/ 07 мая 2019

Протокол Codable swift4 чрезвычайно полезен. Он обеспечивает функции реализации по умолчанию, если конформация определена правильно.

например. это совершенно нормально:

struct Good: Codable {
    var foo: String // Non-optional
    var bar: Int?  // Optional
}

но этот вызовет ошибку компиляции с запросом на создание протокола, соответствующего

struct Bad: Codable {
   var foo: UIButton // Non-optional raise compile error for not conforming Codable Protocol
   var bar: UIView? // optional is okay (not compile error because when decode failed, it fallback to nil)
   var codable: SomeCodable // if the property is also Codable, then it's fine too!
}

Итак, вопрос таков: могу ли я написать протокол, который может требовать, чтобы его соответствие соответствовало самому себе (например, свойства должны соответствовать одному и тому же протоколу)?

Если да, то как? Если нет, то почему?

Кроме того, я также хотел бы знать, как определение CodingKeys внутри структуры может изменить поведение кодирования / декодирования? Могу ли я сделать что-то подобное в моем протоколе?

1 Ответ

2 голосов
/ 07 мая 2019

Мартин правильно, вы не можете сделать это самостоятельно, не касаясь компилятора.

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

struct CodableStruct: Codable {
let primitive: Int // No issues yet

enum CodingKeys: String, CodingKey {
    case primitive
    // This is the default coding key (i.e the JSON has structure ["primitive": 37]
    // You can change this key to anything you need
    //
    // ex case primitive = "any_thing_you_want"
    // JSON has to have structure ["any_thing_you_want": 37]
}

}

Изменение codingKey просто меняет ключ, который будет кодиспользуйте при поиске «декодирования» этого значения из вашего JSON.

Теперь поговорим о компиляторе.Допустим, мы создаем еще одну struct

struct NotCodableStruct {
    let number: Double
}

Эта структура не соответствует Codable.Если мы пойдем и добавим это в нашу предыдущую структуру, то получим:

struct CodableStruct: Codable {
    let primative: Int
    let notCodable: NotCodableStruct // doesn't compile because this doesn't conform to codable

    enum CodingKeys: String, CodingKey {
        case primative
        case notCodable
    }
}

Поскольку NotCodableStruct не соответствует Codable, компилятор жалуется.Другими словами, все переменные в структуре или объекте, которые соответствуют Codable, также должны соответствовать Codable.См. Скриншот ниже для получения дополнительной информации.

compiler error

Конечно, если вы сделаете NotCodableStruct соответствующим Codable, все будут счастливы снова.Поскольку у вас нет возможности обеспечить соблюдение требования, согласно которому все переменные соответствуют Codable, вы не можете создать аналогичный протокол.

...