繁体   English   中英

如何将变量添加到不属于可解码部分的结构?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM