【问题标题】:Swift - custom Decoder has no decode() functionSwift - 自定义解码器没有 decode() 功能
【发布时间】:2020-12-07 01:51:45
【问题描述】:

我创建了一个自定义Decoder,它可以解码非常具体的数据格式,遵循this tutorial。

请注意,我的数据格式不是 XML 或 JSON。

我开始:

public final class MyDecoder: Decoder {
    public var codingPath: [CodingKey] = []
    public var userInfo: [CodingUserInfoKey:Any] = [:]
    public let input: String
    
    public init(_ input: String) {
        self.input = input
    }

    // all stubs are below

并添加了协议所需的所有存根。然后,跟着视频,我还添加了一个符合KeyedDecodingContainerProtocol的struct,并在decode(_ type: String.Type, forKey key: Key)中填写了所需的解析。

为了获取信息,我这样做:

let decoder = MyDecoder(input)
let info = try! myRecord(from: decoder)

到目前为止效果很好。

接下来我想做的是看看是否可以像 JSONDecoder 那样做:

let decoder = MyDecoder()
guard let info = try? decoder.decode(MyInfo.self, from: input) else {
   fatalError("Failed to decode data")
}

但这当然行不通,因为MyDecoder 没有decode() 函数。

所以,我的问题是,如果我添加这个功能,应该在里面放什么?

【问题讨论】:

  • 您可以查看the implementation of JSONDecoder 以更好地了解其工作原理,但一般而言,您编写的符合Decoder 的类型通常是not 实现decode(_:from:) 的顶级类型。 Decoder 用于解码的“中间”和“底层”级别,但顶层接口不同。 JSONDecoder 使用私有 _JSONDecoder 类作为其实际的 Decoder 实例。
  • 换句话说,本教程为您提供了一个有效的 Decoder 实现,但您可能希望将其包装在另一种类型中以提供不同的 API 表面,即 不是 在实际init(from:) 期间可访问。

标签: swift decoder


【解决方案1】:

所以基于非常有用的 cmets,我将代码更改如下。首先我添加了一个顶级的MyDecoder struct,并将原始解码器的名称更改为_MyDecoder。

public struct MyDecoder: TopLevelDecoder, Decodable {
    public typealias Input = String

    public init() {}

    public func decode<T>(_ type: T.Type, from input: String) throws -> T where T : Decodable {
        let decoder = _MyDecoder(input)
        
        return try! MyRecord(from: decoder) as! T
    }    
}

或者,这也可以在不使用TopLevelDecoder 协议的情况下工作(因此可以在

//...

public func decode<T : Decodable>(_ type: T.Type, from data: Data) throws -> T {
   let decoder = _MyDecoder(input)
        
   return try! MyRecord(from: decoder) as! T
}    

现在我可以按如下方式调用解码器:

let decoder = MyDecoder()
return try! decoder.decode(MyRecord.self, from: input)

【讨论】:

    猜你喜欢
    • 2020-07-28
    • 1970-01-01
    • 2022-01-08
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    相关资源
    最近更新 更多