You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何避免多层嵌套的do try catch语句?

解决Swift中do-try-catch嵌套问题

针对多模型解码导致do-try-catch嵌套的问题,有几种简洁的方式可以扁平化代码,后续添加新模型也更方便:

方法1:通用解码函数 + if-else链

先封装一个通用的可选型解码函数,利用try?将解码错误转为nil:

private func attemptDecode<T: Decodable>(_ type: T.Type, from data: Data) -> T? {
    return try? JSONDecoder().decode(type, from: data)
}

然后用if-else依次尝试解码不同模型:

if let sendModel = attemptDecode(SendResponseModel.self, from: data) {
    redirectUserToScreen1(sendModel)
} else if let anotherModel = attemptDecode(SendAnotherResponseModel.self, from: data) {
    redirectUserToScreen2(anotherModel)
} 
// 后续添加新模型只需在这里追加else if分支
else {
    dprint("所有模型解码失败")
}

这种方式完全消除了嵌套,逻辑清晰,新增模型时只需添加新的else if判断即可。

方法2:模型-处理闭包数组(适合大量模型场景)

如果后续要添加的模型很多,可以把"模型类型+对应处理逻辑"封装成数组,通过循环依次尝试:

// 定义元组数组,存储模型类型和对应的成功处理闭包
let decodingTasks: [(modelType: Decodable.Type, handler: (Decodable) -> Void)] = [
    (SendResponseModel.self, { model in
        redirectUserToScreen1(model as! SendResponseModel)
    }),
    (SendAnotherResponseModel.self, { model in
        redirectUserToScreen2(model as! SendAnotherResponseModel)
    })
]

// 遍历数组尝试解码,成功则执行处理逻辑并跳出循环
for task in decodingTasks {
    guard let model = try? JSONDecoder().decode(task.modelType, from: data) else {
        continue
    }
    task.handler(model)
    break
}

// 可选:判断是否所有解码都失败
let allFailed = decodingTasks.allSatisfy { task in
    try? JSONDecoder().decode(task.modelType, from: data) == nil
}
if allFailed {
    dprint("所有模型解码失败")
}

这种方式的优势是新增模型时只需在数组里添加新的元组条目,无需修改判断逻辑,扩展性更强。

补充说明

如果需要单独处理每个模型的解码错误(而非统一捕获),可以把解码函数的返回值改为Result<T, Error>,但上述两种方式已经能解决当前的嵌套问题,且代码更简洁。

内容的提问来源于stack exchange,提问作者fabiobh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:42:25