【问题标题】:Swift 4 decoding/encoding a generic data structureSwift 4 解码/编码通用数据结构
【发布时间】:2019-10-11 19:49:41
【问题描述】:

我有一个通用队列数据结构,它使用数组作为列表,我很难使队列符合可编码和可解码的要求。我有另一个使用队列的类,它也需要是可编码的,但除非它的成员变量是,否则它不能是娇惯的。

我已经尝试使队列符合可编码和可解码,对数据进行编码并将其保存为用户默认值,但这似乎不起作用,实际上我的 init(来自解码器)函数甚至卡在无限循环中原因。我真的可以使用一些帮助

//我的队列

public struct Queue<T: Codable> {

    private var dataSource  = [T]()
    private var userDefaults = UserDefaults()
    public init() {}


    public func isEmpty() -> Bool{

        return  dataSource.isEmpty
    }

    public mutating func enqueue( element: T){
        dataSource.append(element)
   }

   public mutating func dequeue() -> T?{
        return isEmpty() ? nil : dataSource.removeFirst()
    }

    public func peek() -> T? {
        return isEmpty() ? nil : dataSource.first
    }

    public func getCount() -> Int {
        return dataSource.count
    }

    public func printQueue(){
        print(dataSource)
    }
}





public enum Error: String, Swift.Error{
    case queueNotFound = "Queue Not Found!"
}

extension Queue: Encodable, Decodable {
    public func encode(to encoder: Encoder) throws
    {
        let jsonEncoder = JSONEncoder()
        let encodedData = try  jsonEncoder.encode(dataSource)
        userDefaults.set(encodedData, forKey: "queue")
        print(encodedData)
        //var container = encoder.container(keyedBy: CodingKey.self)
    }

    public init(from decoder: Decoder) throws
    {
     print("intilaizing")
        let jsonDecoder = JSONDecoder()
        guard let data = userDefaults.data(forKey: "queue"), let _ =         try? jsonDecoder.decode(Queue.self, from: data)
            else {
                throw Error.queueNotFound
        }

    }

任何类都应该能够将此队列添加为数据成员,当我实现队列时,我相信编码函数可以工作,但解码器会导致一些无限循环

【问题讨论】:

  • 我不应该使用encode的原因是什么?

标签: swift codable decodable encodable


【解决方案1】:

您正在编码dataSource - 这是[T] - 但正在解码Queue,这不起作用。试试

public init(from decoder: Decoder) throws
{
    print("initializing")
    guard let data = userDefaults.data(forKey: "queue") else { throw Error.queueNotFound }
    dataSource = try JSONDecoder().decode([T].self, from: data)
}

顺便说一句,在您的代码中,解码后的值以及潜在的DecodingError 未被使用,这没有任何意义。

【讨论】:

    【解决方案2】:
    extension Queue {
      enum CodingKeys: String, CodingKey {
              case dataSource
     }
    
    
    extension Queue: Encodable, Decodable {
    
    public func encode(to encoder: Encoder) throws
    {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(dataSource, forKey: .dataSource)
    }
    
    public init(from decoder: Decoder) throws
    {
        print("initializing Queue:")
        let data = try decoder.container(keyedBy: CodingKeys.self)
        dataSource = try data.decode(Array.self, forKey: .dataSource)
    }
    

    我改用 CodingKeys,并将类型更改为 Array.self (Array),它与 ​​dataSource 变量 ([T]) 的类型基本相同

    【讨论】:

      猜你喜欢
      • 2019-03-13
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      • 2018-04-08
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2018-08-14
      相关资源
      最近更新 更多