swift 中抛出可选错误的最简洁方法是什么?

What is the cleanest way in swift to throw an optional error?

打开一个可选的并将它传递给我通常使用的函数:

var optionalInt: Int?

optionalInt.map { someFunctionThatTakes(aNonOptional: [=11=]) }

现在我有一个可选的错误,如果它不是 nil,我想抛出它:

var optionalError: Error?

optionalError.map { throw [=12=] }

这行不通,因为传递给 map 的闭包不能抛出。

另一种解决方案是使用完整的 if let 语法:

if let theError = optionalError { throw theError }

但这使用了变量名 theError 两次,并且比漂亮的 .map 实现更容易出错。

有谁知道更简洁的实现方法吗?

This won't work because the closure passed to map can't throw.

事实并非如此。闭包传递给

func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?

可以抛出错误。但这使得 map() 称自己为(重新)抛出表达式,因此必须使用 try:

调用它
var optionalError: Error?
// ...
try optionalError.map { throw [=11=] }

我可能还会用

if let theError = optionalError { throw theError }

这很清楚,并且没有使用 Optional.map 的副作用(丢弃类型 Void? 的 return 值)。

如果不在map方法前面使用try会报错

Call can throw but is not marked with 'try'

相反,使用 try 实际上会引发错误。

enum IntParsingError: Error {
    case overflow
    case invalidInput(String)
}

var optionalError: Error? = IntParsingError.overflow

   do {
    try optionalError.map { throw [=10=] }
   } catch {
     print(error)
   }

你也可以使用 flatMap 因为它评估闭包可选实例不是 nil

optionalError.flatMap(throw [=11=])

But Still, If let would be the best way to handle optional error instead of map and flatMap.

您可以为 Swift.Error

创建扩展
extension Swift.Error {
   func throwIfNeeded() throws {
       throw self
   }
}

并在出现可选错误时调用它

try error?.throwIfNeeded()