带有“尝试?”的故障初始化程序中的“可选类型Self的值?未解包”和“自我”,如何写而无需强行展开

时间:2018-10-05 18:48:28

标签: json swift error-handling codable

我正在尝试在协议中添加JSON反序列化功能,但是无法编译decode函数。如何在不强制展开值的情况下编写初始化程序?

protocol Mappable: Codable {
  init?(jsonString: String)
}

extension Mappable {
  init?(jsonString: String) {
    guard let data = jsonString.data(using: .utf8) else {
        return nil
    }
    // TODO:- Value of optional type 'Self?' not unwrapped error
    self = try? JSONDecoder().decode(Self.self, from: data)
  }
}

2 个答案:

答案 0 :(得分:4)

try?返回一个可选的。但是在一个失败的初始化程序中,您没有将nil分配给self,而是分配给return nil

以下作品:

extension Mappable {
    init?(jsonString: String) {
        guard let data = jsonString.data(using: .utf8) else {
            return nil
        }

        do {
            self = try JSONDecoder().decode(Self.self, from: data)
        } catch {
            return nil
        }
    }
}

正如其他人所说,还需要考虑其他一些事情:

    编码为String data(using:)
  1. .utf8不会失败,因此可以用强制展开的guard代替。
  2. 考虑将其从失败的初始化程序更改为引发错误的初始化程序。

答案 1 :(得分:1)

可抛出的初始化程序在这里会更好地工作:

protocol Mappable: Codable {
    init(jsonString: String) throws
}

extension Mappable {
    init(jsonString: String) throws {
        let data = jsonString.data(using: .utf8)! // this will never be nil
        self = try JSONDecoder().decode(Self.self, from: data)
    }
}

通过这种方式,您的协议不会吞噬错误,并且如果呼叫者不关心错误,则呼叫方可以简单地使用try?