如何在 Swift 中捕获算术溢出错误?

How does one trap arithmetic overflow errors in Swift?

这个可能很简单。我们知道运算符 &+ 对整数进行模运算(环绕),而运算符 + 会导致错误。

$ swift
  1> var x: Int8 = 100
x: Int8 = 100
  2> x &+ x
$R0: Int8 = -56
  3> x + x
Execution interrupted. Enter Swift code to recover and continue.

这是什么错误?我抓不到它,也不能把它变成一个可选的:

  4> do {try x + x} catch {print("got it")}
Execution interrupted. Enter Swift code to recover and continue.
  5> try? x + x
Execution interrupted. Enter Swift code to recover and continue.

我很确定这种错误与 this Stack Overflow question 中的错误相同(被零除),但我不知道是否可以捕获这种错误。我错过了什么简单的事情?能不能困住?如果可以,怎么做?

区分异常和运行时错误。异常被抛出并且可以被捕获。运行时错误会使您的程序停止运行。添加和获取溢出是一个运行时错误,简单明了。没什么可抓的。

&+ 这样的运算符的要点是它不会出错,也不会告诉您有问题。这就是重点。

如果您认为自己可能会溢出,并且想知道自己是否溢出了,请使用像 addWithOverflow 这样的静态方法。它 returns 一个由结果和一个 Bool 组成的元组,表明是否存在溢出。

var x: Int8 = 100
let result = x &+ x // -56

x = 100
let result2 = Int8.addWithOverflow(x,x) // (-56, true)

看起来这已成为 Swift 5 中的非静态方法,addingReportingOverflow(_:)

例如,

UInt8.max.addingReportingOverflow(1)

将 return (partialValue: 0, overflow: true) 查看更多 Int manual page

当然还有以 & 开头的普通算术运算符允许溢出而不会 returning 溢出报告,

UInt8.max &+ 1

会 return 0 作为 UInt8