在Swift中,最清晰的方式是什么来抛出可选错误?

3

要将可选项解包并传递给函数,我通常使用以下方法:

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

有没有人知道一种更简洁的实现方式?


1
在你的 map 语句前面使用 try。 - Jarvis The Avenger
我建议您在处理可选项时使用if let和guard let。 - Jarvis The Avenger
美丽的.map?我认为可选解包更好。 - J. Doe
你怎么会遇到可选错误?这似乎有点奇怪。 - Alexander
3个回答

4

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

这不是真的。传递给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?的返回值)。


0

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

调用可能会抛出异常,但没有标记为 '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,因为它会评估闭包可选实例是否为非nil

optionalError.flatMap(throw $0)

但是,如果使用let关键字来处理可选错误,而不是map和flatMap,将是最好的方式。

0

你可以为 Swift.Error 创建扩展

extension Swift.Error {
   func throwIfNeeded() throws {
       throw self
   }
}

并在可选错误时调用它

try error?.throwIfNeeded()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接