1

我正在开发一个项目来创建一个自定义Decoder来处理非 JSON 数据。

要解码的数据可以是URLs 或Strings。例如:

struct MyData: Decodable {
    let server: URL
    let version: String
}

为了处理这种类型的解码,我实现了一个名为 的类KeyedContainer,它实现了KeyedDecodingContainerProtocol.

对于 aString非常简单,因为我可以使用以下方法:

func decode(_ type: String.Type, forKey key: Key) throws -> String { }

相反,我需要URL依赖以下内容:

func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T: Decodable { }

在其中,我执行以下操作:

func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T: Decodable {
    try checkCanDecodeValue(forKey: key)

    guard let value = configuration[key.stringValue] else {
        let context = DecodingError.Context(codingPath: codingPath, debugDescription: "TODO")
        throw DecodingError.typeMismatch(type, context)
    }

    guard let url = URL(string: value) else {
        let context = DecodingError.Context(codingPath: codingPath, debugDescription: "TODO")
        throw DecodingError.valueNotFound(type, context)
    }

    return url as! T
}

where是直接从自定义解码器configuration传递给的结构。KeyedContainer

这是正确的方法吗?我不确定的是as! T为了让编译器开心而进行的演员阵容。

4

1 回答 1

1

如果你这样做,我不相信你必须硬投到 T :

    guard let url = URL(string: value) as? T else {
        let context = DecodingError.Context(codingPath: codingPath, debugDescription: "TODO")
        throw DecodingError.valueNotFound(type, context)
    }
于 2021-06-18T08:03:31.477 回答