NSError 和 Swift 中的错误

Fer*_*tor 5 error-handling nserror swift do-catch

我已经看到已经有一个关于 Swift和Swift 之间差异的问题,我知道这些差异。但是,我不理解下面代码片段的行为,因为它编译正确。Swift 的错误处理机制要求每个未出现在带有 throws 子句的函数中的 do-catch 块都包含一个通用处理程序(要么不包含任何其他内容,要么包含一个for Error)。然而,使用似乎具有相同的效果。这里有人知道原因吗?我在另一个问题中读到“任何符合 ErrorType 的类都可以转换为 NSError。这些功能在文档中进行了描述。”。然而,该答案指出的文档并没有向我澄清这一点,因为它重点关注我没有使用的 Objective-C。NSErrorErrorcatchcatchNSError

import Foundation
extension Int : Error {}
extension String : Error {}

func fErr() throws {
  let a = Int(readLine()!)!
  if a > 20 {
    throw 42
  } else {
    throw "An error occurred"
  }
}

func gErr() {
  do {
    try fErr()
  } catch let e as NSError {
    print(e)
  }
}
Run Code Online (Sandbox Code Playgroud)

Ita*_*ber 7

在 Darwin 平台(macOS、iOS、tvOS、watchOS)上,Swift 有一个称为桥接的概念,它允许标准库提供的 Swift 类型桥接到Objective-C 类型(通常由 Cocoa 框架提供)。执行此操作的类型包括

\n\n
    \n
  • Array\xe2\x86\x94\xef\xb8\x8eNSArray
  • \n
  • Dictionary\xe2\x86\x94\xef\xb8\x8eNSDictionary
  • \n
  • Set\xe2\x86\x94\xef\xb8\x8eNSSet
  • \n
  • Error\xe2\x86\x94\xef\xb8\x8eNSError
  • \n
  • 等(有关更全面的列表,请参阅上面的链接)
  • \n
\n\n

桥接类型需要编译器支持,并且Error\xe2\x86\x94\xef\xb8\x8eNSError桥接有相当 多的 组件除其他外)。不过,这种桥接允许编译器通常将NSErrors 视为Errors,反之亦然;事实上,正如您在上面的代码片段中看到的,any Error可以转换为 anNSError并返回。

\n\n

您可以在我关于 custom NSErrors的另一个答案中看到实现此目的所需的一些运行时组件,但要点是任何组件都Error可以提供足够的信息来包装在NSError实例中(通过实现var _domainvar _codevar _userInfo),反之亦然。

\n\n

当您捕获错误时as NSError,您会隐式地将Error(无论它是什么)桥接到NSError,就像桥接[1, 2, 3] as NSArrayor一样["foo" : "bar"] as NSDictionary

\n\n

[请注意,桥接目前仅在 Objective-C 运行时可用的情况下可用,即仅在 Darwin 平台上。这种桥接调用在 Linux 上不起作用。]

\n\n

另请参阅SE-0112 改进的 NSError 桥接(最初的 Swift Evolution 提案),了解更多背景信息和更多细节。

\n


Vya*_*lav 1

正如我所看到的,Swift 源代码的某处存在隐式转换。

可能的证明之一是这部分 C++代码 Optional<SILDeclRef> ErrorToNSErrorFn;