[英]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.