要取消包装可选内容并将其传递给我通常使用的功能:
var optionalInt: Int?
optionalInt.map { someFunctionThatTakes(aNonOptional: $0) }
现在我有一个可选错误,如果不是nil,我想抛出该错误:
var optionalError: Error?
optionalError.map { throw $0 }
这行不通,因为传递给map的闭包无法抛出。
另一种解决方案是使用完整的if let
语法:
if let theError = optionalError { throw theError }
但这两次使用了变量名theError
,比漂亮的.map
实现更容易出错。
有人知道更干净的方法来实现这一点吗?
答案 0 :(得分:4)
这行不通,因为传递给map的闭包无法抛出。
那不是事实。封闭传递给
func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?
可以抛出错误。但这使map()
称自己为一个(重新)抛出的表达式,因此必须使用try
来调用它:
var optionalError: Error?
// ...
try optionalError.map { throw $0 }
我可能仍会使用
if let theError = optionalError { throw theError }
这非常清楚,并且没有使用Optional.map
的副作用(丢弃Void?
类型的返回值)。
答案 1 :(得分:0)
如果您未在地图方法前使用try
,则会出现错误
通话可以抛出但未标记为“尝试”
相反,请使用try
来实际引发错误。
enum IntParsingError: Error {
case overflow
case invalidInput(String)
}
var optionalError: Error? = IntParsingError.overflow
do {
try optionalError.map { throw $0 }
} catch {
print(error)
}
您还可以使用flatMap,因为它会评估Closure可选实例不是nil
optionalError.flatMap(throw $0)
但是,如果让它成为处理可选错误的最好方法 而不是map和flatMap。
答案 2 :(得分:0)
您可以为Swift.Error创建扩展名
extension Swift.Error {
func throwIfNeeded() throws {
throw self
}
}
并在发生可选错误时调用它
try error?.throwIfNeeded()