【发布时间】:2015-10-22 03:40:27
【问题描述】:
导致过滤函数throws 或rethrows 出错的触发器可能是什么?someArray.filter(includeElement: (Self.Generator.Element) throws -> Bool )
【问题讨论】:
导致过滤函数throws 或rethrows 出错的触发器可能是什么?someArray.filter(includeElement: (Self.Generator.Element) throws -> Bool )
【问题讨论】:
“触发器”是闭包内存在一些可能引发错误的代码,即闭包内有一个try。
filter 方法被定义为不仅接受可能引发错误的闭包,而且还重新引发其闭包引发的任何错误。因此,如果您使用引发错误的闭包调用 filter(即闭包具有 try 语句),则可以将整个 filter 包装在其自己的 do-try-catch 模式中优雅地处理其闭包可能引发的任何错误。
do {
let result = array.filter {
// some code with `try` in it here
return success
}
} catch {
print(error)
}
例如,假设您有一些Fraction 类型,当您尝试calculateValue 时,当分母为零时,它会抛出一些自定义Error。
enum MathError: Error {
case divideByZero
}
struct Fraction {
let numerator: Int
let denominator: Int
func calculateValue() throws -> Double {
if denominator == 0 {
throw MathError.divideByZero
}
return Double(numerator) / Double(denominator)
}
}
然后您可以执行以下操作:
let fractions = [
Fraction(numerator: 1, denominator: 3),
Fraction(numerator: 5, denominator: 7),
Fraction(numerator: 4, denominator: 0)
]
do {
let biggerThanOneHalf = try fractions.filter {
try $0.calculateValue() > 0.5
}
print(biggerThanOneHalf)
} catch {
print(error)
}
显然,如果您提供给 filter 的闭包没有引发任何错误(即闭包中没有 try),那么您不必担心 filter 会重新抛出任何错误,并且不会do-catch 块根本不需要:
let numbers = [0, 1, 2, 3, 4, 5]
let evenNumbers = numbers.filter { $0 % 2 == 0 }
对于 Swift 2 版本,请参阅之前的 revision of this answer。
【讨论】:
do-catch 块中并在 filter 闭包内使用 try 。但是如果你没有做任何引发错误的事情(即你没有在闭包内使用try),那么就不需要do-catch 的东西,它只是let result = array.filter { ... }。