我可以编写类似于可编码和可解码的协议的行为吗?

时间:2019-05-07 07:28:40

标签: swift swift4 swift-protocols codable

swift4的Codable协议非常有用。如果正确定义了构象,它将提供默认的实现功能。

例如这完全没问题:

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 个答案:

答案 0 :(得分:2)

Martin是正确的,如果不接触编译器,您将无法自行实现。

首先让我们看一下这个基本示例,在该示例中解释如何使用编码键。

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

}

更改encodingKey只是更改了当您希望从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的要求,因此您无法制定类似的协议。