ios - ios meta:我如何摆脱丑陋的雏菊
问题描述
public protocol NodeProtocol
{
var identifier: String? { get }
...
}
var node: (NodeProtocol)?
required public init(from decoder: Decoder) throws
{
let values = try decoder.container(keyedBy: CodingKeys.self)
do {
node = try values.decode(Operation.self, forKey: .node)
} catch {
do {
node = try values.decode(Deposit.self, forKey: .node)
} catch {
do {
node = try values.decode(Loan.self, forKey: .node)
}
catch {
print ("failure \(error) decoding node")
}
}
}
}
我怎么能把这种丑陋折叠成一个循环,将 Foo.self 转储到一个数组中?
public class BVOperation: Codable { ...
public struct Loan: Codable { ...
public struct Deposit: Codable { ...
如果你尝试这样的事情:
让 types = [Operation.self, Loan.self, Deposit.self] 为 [Any]
let values = try decoder.container(keyedBy: CodingKeys.self)
for type in types {
do {
node = try values.decode(type as! (NodeProtocol)?.Type, forKey: .node)
break
} catch {
continue
}
}
解决方案
最好的方法是在您的序列化数据中使用类型键,但如果这不可能,您可以通过执行以下操作来获得一些更好看的代码:
let types = [Operation.self, Loan.self, Deposit.self]
let values = try decoder.container(keyedBy: CodingKeys.self)
for type in types {
do {
node = try values.decode(type, forKey: .node)
break
} catch {
continue
}
}
此外,do ... catch
如果您不喜欢它们,则不需要使用它们。您可以改用可选绑定:
let types = [Operation.self, Loan.self, Deposit.self]
let values = try decoder.container(keyedBy: CodingKeys.self)
for type in types {
guard let decoded = try? values.decode(type, forKey: .node) else { continue }
node = decoded
break
}
他们也会这样做,但这是一个偏好问题。
推荐阅读
- python - Python列表理解多个if else条件
- javascript - 动态导入:我错过了什么吗?
- android - nativescript 保存 blob 错误无法将对象转换为 [B at index 1
- angular - 为什么输入字段为空白时Angular8 form.status VALID?
- javascript - 为什么 axios 会抓取整个 html 页面?
- mysql - 连接到主服务器
- java - CompletableFuture 链不调用 thenAcceptAsync
- javascript - 在 Cognos Analytics 11 报告中使用 MermaidJS
- flutter - 如何在我的项目中应用flutter_bloc?
- authentication - Blazor 客户端 (webassembly) Facebook 或 Google 登录