正如问题所述:我有一个符合新Encodable
协议的结构,并希望在结构本身中插入不作为变量或常量出现的键和值。我目前的解决方法是将它们作为常量添加到结构中,其唯一目的是添加到生成的JSON输出中。有没有办法在func encode(to encoder: Encoder) throws { ... }
?
我有一个相当大的Swift 4项目需要JSON输出来生成项目本身之外的统计信息和可视化,因此几乎所有的结构,类和枚举都符合新的Encodable
协议。输出已经在工作,但在某些方面可读性很差。特别是在一个描述栅格化工厂布局中的字段的结构中:
该字段的位置(包含坐标x: Int
和y: Int
)以及包含以下情况的自定义enum FieldType
的内容:
case wall
case entrance(robots: Set<Robot>)
case exit(robots: Set<Robot>)
case workstation(object: Workstation)
case robot(object: Robot)
case empty
Position
,FieldType
,Robot
,Workstation
和Field
本身已经实现Encodable
,但问题是我的JSON输出对于字段看起来像这样:
...
{
"content" : "empty",
"position" : {
"x" : 9,
"y" : 6
}
},
{
"content" : "empty",
"position" : {
"x" : 10,
"y" : 6
}
},
{
"content" : {
"id" : 3,
"state" : "idle",
"type" : "C",
"position" : {
"x" : 11,
"y" : 6
}
},
"position" : {
"x" : 11,
"y" : 6
}
},
{
"content" : "empty",
"position" : {
"x" : 12,
"y" : 6
}
},
...
正如您所看到的,在位置(11,6)处存在除空字段之外的其他内容,但是在我的模拟中不知道只有工作站具有空闲状态,则无法知道该字段所包含的内容。所以我尝试将值"object"
添加到我的工作站模型(机器人模型中的类比"workstation"
),方法是将CodingKeys定义为枚举:
"robot"
这导致我的private enum CodingKeys: String, CodingKey {
case object
case id
case state
case type
case position
}
不再符合struct Workstation
。所以我找到的唯一解决方案是添加常量Encodable
,但这是一个常量,其唯一目的是添加到输出中,我想避免这种情况。
答案 0 :(得分:1)
您必须为FieldType
编写自定义编码器:
enum FieldType: Encodable {
case wall
case entrance(robots: Set<Robot>)
case exit(robots: Set<Robot>)
case workstation(object: Workstation)
case robot(object: Robot)
case empty
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .wall:
try container.encode("wall")
case .entrance(let robotset):
try container.encode(robotset)
case .exit(let robotSet):
try container.encode(robotSet)
case .workstation(let workstation):
try container.encode(workstation)
case .robot(let robot):
try container.encode(robot)
case .empty:
try container.encode("empty")
}
}
}
(这假设Robot
和Workstation
已经Encodable
)