使结构可编码的问题

问题描述 投票:0回答:1

我有 Application 2个变量的协议。而我有 component 的结构,它有一个变量,它确认了向 Application 协议。我需要保存这个 struct 在磁盘中。所以我确认它是 Codable 协议。当我这样做时,我得到了这样一个错误。

"协议类型`应用'不能符合`可解码',因为只有具体类型才能符合协议"

这是我的代码。

public protocol Application {
     var name : String {get}
     var ownerName : String {get}
}

public struct component : Codable {
     let application : Application
     private enum CodingKeys: String, CodingKey {
           case application
       }

public init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        application = try values.decode(Application.self, forKey: .application)
    }

 public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(application, forKey: .application)
    }
 }

我是新来的Swift,所以如果我错过了一些非常明显的东西,对不起。我不能够解决这个问题,我需要一些帮助,在正确的方向。先谢谢你。

swift codable decodable encodable
1个回答
3
投票

如何解决这个问题很大程度上取决于你要解决的问题。

如果你想在JSON中准确地存储和加载这两个键,那么Application应该是一个结构(正如jawadAli指出的那样)。

如果你的意思是要存储更多的信息,但一个给定的Component恰好与一种类型的Application绑定,那么你希望Component是通用的。

public struct Component<App: Application & Codable> : Codable {
     let application : App
     ...
}

请注意添加 & Codable. 如果所有符合Application的东西都应该是Codable的,那么你可以把这一点作为一个要求 Application:

public protocol Application: Codable {
     var name : String {get}
     var ownerName : String {get}
}

重要的是要理解,这并不使Application符合Codable。这意味着,为了符合Application,一个类型也必须符合Codable。对一个抽象类型(即协议)进行解码是不可能的。

如果你的意思是要存储更多的信息,但一个给定的Component实际上并不知道它持有什么样的Application,那么这是一个更复杂的问题(而且往往过于复杂,应该重新考虑;如果你发现你使用了大量的 as? 测试,那么你几乎应该重新设计)。) 如果这是你的问题,你应该再解释一下你解决的是什么问题,我们可以讨论如何解决。(一般需要某种动态类型注册系统,以及支持类型元数据的JSON格式。也可以换成NSCoder,不用JSON)。)


2
投票

使用Struct是确认到codable而不是协议就可以解决这个问题了

public struct Application : Codable {
     var name : String
     var ownerName : String
}
© www.soinside.com 2019 - 2024. All rights reserved.