0

我有Application2 个变量的协议。而且我有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 新手,如果我遗漏了一些非常明显的东西,我很抱歉。我无法解决这个问题,我需要一些正确方向的帮助。先感谢您。

4

2 回答 2

3

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

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

如果您打算存储更多信息,但给定的 Component 只与一种类型的应用程序相关联,那么您希望 Component 是通用的:

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

注意添加& Codable。如果所有符合应用程序的东西都应该是可编码的,那么您可以要求Application

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

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

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

于 2020-05-07T17:59:34.020 回答
2

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

public struct Application : Codable {
     var name : String
     var ownerName : String
}
于 2020-05-07T17:55:38.233 回答