[英]How to add variable to a struct which does not part of decodable?
我会使用可解码的nodesWithDepth
:
这以前有效:
public struct NEWTREE: Equatable, Codable {
public var Filename: String
public var GROUP: [GROUP]
public var ITEM: [ITEM]
public var CATEGORY: [CATEGORY]
public var ROOT: ROOT
但修改后的不是:
public struct NEWTREE: Equatable, Codable {
public var Filename: String
public var GROUP: [GROUP]
public var ITEM: [ITEM]
public var CATEGORY: [CATEGORY]
public var ROOT: ROOT
public var nodesWithDepth: [(text: String, depth: Int, type: TreeData2)]?
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
Filename = try container.decode(String.self, forKey: .Filename)
GROUP = try container.decode([GROUP].self, forKey: .GROUP)
ITEM = try container.decode([ITEM].self, forKey: .ITEM)
CATEGORY = try container.decode([CATEGORY].self, forKey: .CATEGORY)
ROOT = try container.decode(ROOT.self, forKey: .ROOT)
}
private enum CodingKeys: String, CodingKey {
case Filename
case GROUP
case ITEM
case CATEGORY
case ROOT
}
但这会引发错误:
无法将类型“[[GROUP]]”的值转换为预期的参数类型“[GROUP].Type”
我该如何解决?
Swift 被诸如
[GROUP].self
显然,编译器认为这里的GROUP
指的是属性GROUP
,而不是类型GROUP
。 请注意,将.self
添加到任何表达式都是完全有效的,而不改变其含义。
如此有效,您正在传递一个单元素数组,其中包含属性GROUP
的值。 该表达式的类型为[[GROUP]]
,但decode
显然需要可解码的元类型,因此会出现错误。
或者在ROOT
的情况下,您正在传递ROOT
属性的值,该属性的类型为ROOT
,但decode
显然需要一个可解码的元类型。
这种行为可以用一个更小的例子来展示,如下所示:
struct A {}
struct B {
let A: A
func f() {
print(A.self)
print([A].self)
}
}
B(A: A()).f()
print("-------")
print(A.self)
print([A].self)
B
外部的两个打印语句打印元类型,而B
内部的两个打印语句打印A
的一个实例和一个数组。
您可以使用数组类型的长格式Array<Group>.self
来解决这种歧义
GROUP = try container.decode(Array<GROUP>.self, forKey: .GROUP)
或者在ROOT
等情况下引入类型别名:
typealias ROOTType = ROOT
...
ROOT = try container.decode(ROOTType.self, forKey: .ROOT)
但是,当然,如果您遵守 Swift 命名准则,那么这一切都不会发生,并且:
var groups: [Group]
如果您希望编码键全部大写,可以在编码键枚举中进行:
public struct NewTree: Equatable, Codable {
public var filename: String
public var groups: [Group]
public var items: [Item]
public var categories: [Category]
public var root: Root
// consider making the tuple here into another struct...
public var nodesWithDepth: [(text: String, depth: Int, type: TreeData2)]?
// you don't actually need to write the custom decoding logic just because you added nodesWithDepth
// Swift can figure it out from the CodingKeys enum because the
// case names match the property names
private enum CodingKeys: String, CodingKey {
case filename = "Filename"
case groups = "GROUP"
case items = "ITEM"
case categories = "CATEGORY"
case root = "ROOT"
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.