使结构可编码的问题

Issue in making a struct Codable

我有 Application 带有 2 个变量的协议。我有 component 结构,它有一个变量,它确认 Application 协议。我需要将此 struct 保存在磁盘中。所以我确认它符合 Codable 协议。这样做时我遇到了这样的错误,

"Protocol type 'Application' cannot conform to 'Decodable' because only concrete types can conform to protocols"

这是我的代码,

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 的新手,如果我遗漏了一些非常明显的东西,我深表歉意。我无法解决这个问题,我需要一些正确方向的帮助。先感谢您。

使用确认可编码的结构而不是协议将解决问题

public struct Application : Codable {
     var name : String
     var ownerName : String
}

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

如果您想在 JSON 中准确地存储和加载这两个键,那么 Application 应该是一个结构(如 jawadAli 注释)。

如果您打算存储更多信息,但给定的组件只绑定到一种类型的应用程序,那么您希望组件是通用的:

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}
}

重要的是要了解这不会使应用程序符合 Codable。这意味着为了符合 Application,类型也必须符合 Codable。永远不可能解码抽象类型(即协议)。

如果你想存储更多的信息,但一个给定的组件实际上并不知道它持有什么样的应用程序,那么这是一个更复杂的问题(而且往往过于复杂,应该重新考虑;如果你发现你使用了很多 as? 测试,那么你几乎肯定应该重新设计)。如果那是你的问题,你应该多解释一下你正在解决什么问题,我们可以讨论如何解决它。 (它通常需要某种动态类型注册系统,以及支持类型元数据的 JSON 格式。或者您可以切换到 NSCoder 而不使用 JSON。)