嵌套 do catch swift 3.0
Nested do catch swift 3.0
我想使用连续的 try 语句。如果一个 return 是一个错误,我想继续下一个,否则 return 值。
下面的代码似乎工作正常,但我最终会得到一个大的嵌套 do catch 金字塔。在 Swift 3.0 中有 smarter/better 的方法吗?
do {
return try firstThing()
} catch {
do {
return try secondThing()
} catch {
return try thirdThing()
}
}
如果不需要从那些函数调用中抛出的实际错误
然后你可以使用 try?
将结果转换为可选的,
并使用零合并运算符 ??
.
链接调用
例如:
if let result = (try? firstThing()) ?? (try? secondThing()) ?? (try? thirdThing()) {
return result
} else {
// everything failed ...
}
或者,如果一切都失败了,最后一个方法的错误应该被抛出,
对除最后一个方法调用之外的所有方法使用 try?
:
return (try? firstThing()) ?? (try? secondThing()) ?? (try thirdThing())
如果 Martin 的回答对您来说过于简洁,您可以使用单独的 catch 块。
do {
return try firstThing()
} catch {}
do {
return try secondThing()
} catch {}
do {
return try thirdThing()
} catch {}
return defaultThing()
由于每个抛出函数的结果都会立即返回,因此无需嵌套。
另一种方法是编写一个将所有抛出函数作为参数的函数。它returns第一个成功执行或为零。
func first<T>(_ values: (() throws -> T)...) -> T? {
return values.lazy.flatMap({ (throwingFunc) -> T? in
return try? throwingFunc()
}).first
}
lazy 确保仅在找到第一个匹配项之前调用这些值。这样做,你也可以很快的添加很多案例。
你可以这样使用函数
return first(firstThing, secondThing, thirdThing) ?? "Default"
我还包括了我用来在操场上测试它的代码:
enum ThingError: Error {
case zero
}
func firstThing() throws -> String {
print("0")
throw ThingError.zero
return "0"
}
func secondThing() throws -> String {
print("1")
return "1"
}
func thirdThing() throws -> String {
print("2")
return "B"
}
func first<T>(_ values: (() throws -> T)...) -> T? {
return values.lazy.flatMap({ (throwingFunc) -> T? in
return try? throwingFunc()
}).first
}
func tryThings() -> String {
return first(firstThing, secondThing, thirdThing) ?? "Default"
}
tryThings() // prints "0" and "1"
我想使用连续的 try 语句。如果一个 return 是一个错误,我想继续下一个,否则 return 值。 下面的代码似乎工作正常,但我最终会得到一个大的嵌套 do catch 金字塔。在 Swift 3.0 中有 smarter/better 的方法吗?
do {
return try firstThing()
} catch {
do {
return try secondThing()
} catch {
return try thirdThing()
}
}
如果不需要从那些函数调用中抛出的实际错误
然后你可以使用 try?
将结果转换为可选的,
并使用零合并运算符 ??
.
例如:
if let result = (try? firstThing()) ?? (try? secondThing()) ?? (try? thirdThing()) {
return result
} else {
// everything failed ...
}
或者,如果一切都失败了,最后一个方法的错误应该被抛出,
对除最后一个方法调用之外的所有方法使用 try?
:
return (try? firstThing()) ?? (try? secondThing()) ?? (try thirdThing())
如果 Martin 的回答对您来说过于简洁,您可以使用单独的 catch 块。
do {
return try firstThing()
} catch {}
do {
return try secondThing()
} catch {}
do {
return try thirdThing()
} catch {}
return defaultThing()
由于每个抛出函数的结果都会立即返回,因此无需嵌套。
另一种方法是编写一个将所有抛出函数作为参数的函数。它returns第一个成功执行或为零。
func first<T>(_ values: (() throws -> T)...) -> T? {
return values.lazy.flatMap({ (throwingFunc) -> T? in
return try? throwingFunc()
}).first
}
lazy 确保仅在找到第一个匹配项之前调用这些值。这样做,你也可以很快的添加很多案例。
你可以这样使用函数
return first(firstThing, secondThing, thirdThing) ?? "Default"
我还包括了我用来在操场上测试它的代码:
enum ThingError: Error {
case zero
}
func firstThing() throws -> String {
print("0")
throw ThingError.zero
return "0"
}
func secondThing() throws -> String {
print("1")
return "1"
}
func thirdThing() throws -> String {
print("2")
return "B"
}
func first<T>(_ values: (() throws -> T)...) -> T? {
return values.lazy.flatMap({ (throwingFunc) -> T? in
return try? throwingFunc()
}).first
}
func tryThings() -> String {
return first(firstThing, secondThing, thirdThing) ?? "Default"
}
tryThings() // prints "0" and "1"