快速抛出可选错误的最干净方法是什么?

时间:2019-01-30 12:58:23

标签: swift try-catch optional throws

要取消包装可选内容并将其传递给我通常使用的功能:

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实现更容易出错。

有人知道更干净的方法来实现这一点吗?

3 个答案:

答案 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()