我可以编写类似于 Encodable 和 Decodable 的协议吗?
Can I write protocol behave similar to Encodable & Decodable?
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
如何改变 encode/decode 行为?我也可以在我的协议中做类似的事情吗?
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]
}
}
更改 codingKey 只是更改代码在从您的 JSON 中查找 "decode" 该值时将使用的密钥。
现在让我们谈谈编译器。假设我们创建了另一个 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
。有关详细信息,请参见下面的屏幕截图。
当然,如果你让 NotCodableStruct
符合 Codable
,每个人都会再次开心。由于您无法强制要求所有变量都符合 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
如何改变 encode/decode 行为?我也可以在我的协议中做类似的事情吗?
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]
}
}
更改 codingKey 只是更改代码在从您的 JSON 中查找 "decode" 该值时将使用的密钥。
现在让我们谈谈编译器。假设我们创建了另一个 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
。有关详细信息,请参见下面的屏幕截图。
当然,如果你让 NotCodableStruct
符合 Codable
,每个人都会再次开心。由于您无法强制要求所有变量都符合 Codable
的要求,因此您无法制定类似的协议。