Swift 将错误绑定到变量的捕获模式
Swift Catch Pattern that binds the error to a variable
使用 Swift 4.2 和 XCode 10
在Swift4.2中,DecodingError是一个枚举。有(目前)四种不同的情况。我可以分别捕获每个案例,并绑定可用于记录错误的变量,如以下代码所示...
do {
let model = try jsonDecoder.decode(BattleShip.self, from: jsonData!)
print(model)
} catch DecodingError.dataCorrupted(let context) {
print(context.debugDescription)
} catch DecodingError.keyNotFound(let key, let context) {
print("\(key.stringValue) was not found, \(context.debugDescription)")
} catch DecodingError.typeMismatch(let type, let context) {
print("\(type) was expected, \(context.debugDescription)")
} catch DecodingError.valueNotFound(let type, let context) {
print("no value was found for \(type), \(context.debugDescription)")
} catch {
print("I know not this error")
}
但是在我可能遇到解码错误的所有地方都放了很多代码。而且,如果我的 do{} 块有多个调用抛出,我可能需要处理这些方法以不同方式调用的错误。我试图实现的模式看起来像这样......其中 decodingError(error) 包含上面所有的混乱代码
do {
let object1 = try decoder.decode(SomeClass.self, from: someData)
try object2.methodThatThrowsSomeOtherError()
} catch <all decoding errors> { // this is invalid pseudocode
MyCentralLogger.log.decodingError(error)
} catch let nonDecodingError {
MyCentralLogger.log.error(nonDecodingError)
}
我可以有一个像这样的 catch 模式似乎可以满足所有枚举情况(至少它可以编译)
} catch is DecodingError {
但是编译器似乎没有自动绑定 'error' 变量,而且我没有看到任何像
这样的选项
} catch let decodingError is DecodingError { // THIS IS NOT VALID
如果我只捕获所有错误,我可以轻松地在中央方法中进行切换,适当地分隔不同的解码错误情况。但我希望能够避免将非解码错误发送到该交换机。我还可以将我的 do{} 块分开,以便我只在其中执行解码步骤,但这也会使代码变得混乱,特别是如果您正在解码散布在其他操作中的多条消息。
建议?谢谢大家!
catch
行中使用的语法与 switch
的 case
中使用的模式语法完全相同。如果您知道如何写 case
,您就会知道如何写 catch
.
因此,例如,您抱怨:
} catch let decodingError is DecodingError { // THIS IS NOT VALID
没错。但是这个是有效的:
} catch let decodingError as DecodingError {
哦,一个字母有多么不同。
这仍然比预期的代码多很多,但可能更简洁一些:
} catch DecodingError.keyNotFound(_, let context),
DecodingError.valueNotFound(_, let context),
DecodingError.typeMismatch(_, let context),
DecodingError.dataCorrupted(let context) {
print(context.debugDescription)
MyCentralLogger.log.decodingError(context.underlyingError)
} catch {
print(error.localizedDescription)
MyCentralLogger.log.error(error)
}
结合有效答案和 switch
语句,以下将为您节省一些几乎相同的行:
do {
let model = try jsonDecoder.decode(BattleShip.self, from: jsonData!)
print(model)
} catch let decodingError as DecodingError {
switch decodingError {
case .typeMismatch(_, let c), .valueNotFound(_, let c), .keyNotFound(_, let c), .dataCorrupted(let c):
print(c.debugDescription)
}
} catch {
print(error.debugDescription)
}
如果,f.i,你的解码数据遗漏了属性 index: Int
,它会打印
No value associated with key CodingKeys(stringValue: "index",
intValue: nil) ("index").
对于调试目的,这应该足够清楚了。
使用 Swift 4.2 和 XCode 10
在Swift4.2中,DecodingError是一个枚举。有(目前)四种不同的情况。我可以分别捕获每个案例,并绑定可用于记录错误的变量,如以下代码所示...
do {
let model = try jsonDecoder.decode(BattleShip.self, from: jsonData!)
print(model)
} catch DecodingError.dataCorrupted(let context) {
print(context.debugDescription)
} catch DecodingError.keyNotFound(let key, let context) {
print("\(key.stringValue) was not found, \(context.debugDescription)")
} catch DecodingError.typeMismatch(let type, let context) {
print("\(type) was expected, \(context.debugDescription)")
} catch DecodingError.valueNotFound(let type, let context) {
print("no value was found for \(type), \(context.debugDescription)")
} catch {
print("I know not this error")
}
但是在我可能遇到解码错误的所有地方都放了很多代码。而且,如果我的 do{} 块有多个调用抛出,我可能需要处理这些方法以不同方式调用的错误。我试图实现的模式看起来像这样......其中 decodingError(error) 包含上面所有的混乱代码
do {
let object1 = try decoder.decode(SomeClass.self, from: someData)
try object2.methodThatThrowsSomeOtherError()
} catch <all decoding errors> { // this is invalid pseudocode
MyCentralLogger.log.decodingError(error)
} catch let nonDecodingError {
MyCentralLogger.log.error(nonDecodingError)
}
我可以有一个像这样的 catch 模式似乎可以满足所有枚举情况(至少它可以编译)
} catch is DecodingError {
但是编译器似乎没有自动绑定 'error' 变量,而且我没有看到任何像
这样的选项} catch let decodingError is DecodingError { // THIS IS NOT VALID
如果我只捕获所有错误,我可以轻松地在中央方法中进行切换,适当地分隔不同的解码错误情况。但我希望能够避免将非解码错误发送到该交换机。我还可以将我的 do{} 块分开,以便我只在其中执行解码步骤,但这也会使代码变得混乱,特别是如果您正在解码散布在其他操作中的多条消息。
建议?谢谢大家!
catch
行中使用的语法与 switch
的 case
中使用的模式语法完全相同。如果您知道如何写 case
,您就会知道如何写 catch
.
因此,例如,您抱怨:
} catch let decodingError is DecodingError { // THIS IS NOT VALID
没错。但是这个是有效的:
} catch let decodingError as DecodingError {
哦,一个字母有多么不同。
这仍然比预期的代码多很多,但可能更简洁一些:
} catch DecodingError.keyNotFound(_, let context),
DecodingError.valueNotFound(_, let context),
DecodingError.typeMismatch(_, let context),
DecodingError.dataCorrupted(let context) {
print(context.debugDescription)
MyCentralLogger.log.decodingError(context.underlyingError)
} catch {
print(error.localizedDescription)
MyCentralLogger.log.error(error)
}
结合有效答案和 switch
语句,以下将为您节省一些几乎相同的行:
do {
let model = try jsonDecoder.decode(BattleShip.self, from: jsonData!)
print(model)
} catch let decodingError as DecodingError {
switch decodingError {
case .typeMismatch(_, let c), .valueNotFound(_, let c), .keyNotFound(_, let c), .dataCorrupted(let c):
print(c.debugDescription)
}
} catch {
print(error.debugDescription)
}
如果,f.i,你的解码数据遗漏了属性 index: Int
,它会打印
No value associated with key CodingKeys(stringValue: "index", intValue: nil) ("index").
对于调试目的,这应该足够清楚了。