swift - 多个可编码实现
问题描述
假设我有一个对象 ,Game
它包含三个属性score
,firstName
,lastName
。
class Game: Encodable {
var firstName: String
var lastName: String
var score: Int
enum CodingKeys: String, CodingKey {
case firstName
case lastName
case score
}
func encode(to encoder: Encoder) throws {
var encoder = encoder.container(keyedBy: CodingKeys.self)
try? encoder.encode(self.firstName, forKey: .firstName)
try? encoder.encode(self.lastName, forKey: .lastName)
try? encoder.encode(self.score, forKey: .score)
}
}
假设我想将它保存到磁盘,我可以使用JSONEncoder
let game = Game(firstName: "John", lastName: "Smith", score: 42)
let data = try JSONEncoder().encode(game)
{
firstName: "John",
lastName: "Smith",
score: 42
}
现在我希望用户能够自己生成 JSON 并将其共享给任何应用程序,但出于隐私原因,我想省略姓氏,如何encode(to encoder: Encoder)
为一种类型创建两个实现?
示例输出:
{
firstName: "John",
score: 42
}
解决方案
有一些选择。除了 Sandeep 的带有 Bool 标志的解决方案之外,多态性可能是另一种解决方案:
final class ShareableGame: Game {
init(_ game: Game) {
super.init(firstName: game.firstName,
lastName: game.lastName,
score: game.score)
}
override func encode(to encoder: Encoder) throws {
var encoder = encoder.container(keyedBy: CodingKeys.self)
try? encoder.encode(self.firstName, forKey: .firstName)
try? encoder.encode(self.score, forKey: .score)
}
}
let game = Game(firstName: "John", lastName: "Smith", score: 42)
let shareableGame = ShareableGame(game)
let shareableGameData = try JSONEncoder().encode(shareableGame)
print(String(bytes: shareableGameData, encoding: .utf8)!)
// {"firstName":"John","score":42}
(假设 Game 类的定义与此类似:)
class Game: Encodable {
let firstName: String
let lastName: String
let score: Int
init(firstName: String, lastName: String, score: Int) {
self.firstName = firstName
self.lastName = lastName
self.score = score
}
/*
encode(to:) throws can be omitted, since the default
implementation is exactly as expected.
*/
enum CodingKeys: String, CodingKey {
// Cannot be omitted, since it's used in subclasses.
case firstName
case lastName
case score
}
}
推荐阅读
- php - 如何不打印等于使用 php 脚本登录的用户的会话名称的 mysql 表值
- ioctl - nvme-cli 发送 io-passthru,data_len 等于 max_sectors_kb,显示“passthru:无效参数”
- javascript - 提交表单时如何调用API?
- azure-active-directory - Azure Active Directory(AAD) 默认生成具有 90 天滑动到期的令牌。如何减少相同的滑动到期时间?
- ios - 如果设备日期在 Swift 中更改,则计时器递减时间会更改
- php - 复合键的 Laravel 验证
- java - Hibernate+ postgres 批量更新不起作用
- c# - 如何在 NOPCOMMERCE app 中使用开发和生产环境?
- javascript - 在离子电容器 ios 平台中出现错误:仅在浏览器 HTTP/HTTPS 环境中支持 RecaptchaVerifier
- apache-spark - Zeppelin 0.9 在 YARN 客户端模式下运行 Spark 笔记本,但不是 YARN 集群