【问题标题】:How does one trap arithmetic overflow errors in Swift?如何在 Swift 中捕获算术溢出错误?
【发布时间】:2016-06-28 16:28:13
【问题描述】:

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

$ 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 中的错误相同(被零除),但我不知道这种错误是否可以被捕获。我错过了什么简单的事情?能不能被困住?如果有,怎么做?

【问题讨论】:

    标签: swift error-handling integer-overflow


    【解决方案1】:

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

    例如,

    UInt8.max.addingReportingOverflow(1)
    

    将返回(partialValue: 0, overflow: true)Int manual page 上查看更多信息

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

    UInt8.max &+ 1
    

    0 作为UInt8 返回

    【讨论】:

      【解决方案2】:

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

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

      如果您认为您可能会溢出,并且想知道是否发生了溢出,请使用 addWithOverflow 等静态方法。它返回一个由结果组成的元组和一个说明是否存在溢出的 Bool。

      var x: Int8 = 100
      let result = x &+ x // -56
      
      x = 100
      let result2 = Int8.addWithOverflow(x,x) // (-56, true)
      

      【讨论】:

      • 谢谢,我知道这不是一个抛出的错误(你说的例外,尽管苹果似乎避免使用这个术语),因为它无法被捕获;我想知道是否有某种方法可以“捕获它”。 Swift 中的运行时错误可能是无法捕获的;那将是一个很好的答案。我只是找不到任何明确说明情况的信息。你有参考吗?我想我可以更好地说明这个问题。我想确定这些不能处理。
      • 未捕获的异常是运行时错误。但并非每个运行时错误都是可捕获的异常。当文档告诉您某些事情“是运行时错误”时,他们是在告诉您,您永远无法摆脱做这件事;它会阻止你的程序死机。例如,超出范围是运行时错误。
      • 顺便说一句,我理解你的问题(在你的评论中),但我只能告诉你这是一个设计决定。我讨论了为什么他们没有将超出范围之类的事情作为可捕获的异常,答案高于我的工资等级;看来这太贵了。您需要与计算机科学家交谈以了解更多信息。 :)
      • 或者你可以相信我。 :) 无论如何,我希望你明白我的意思是:所有运行时错误都可能是可捕获的想法一点也不傻,许多语言都是这样工作的。 (你可能已经知道了。)但 Objective-C 和 Swift 不知道。在超出范围的情况下,如果有一些特殊的语法意味着“我愿意在这里付出额外的代价,请让我抓住这个而不是让我的程序崩溃”,这将是非常酷的。实际上,这就是他们对整数溢出所做的事情。但是对于超出范围之类的其他东西,就没有这样的东西了。
      • @ThomasTempelmann 这是一个由来已久的抱怨,在 Swift 4 中解决了,所以升级到 Xcode 9 并开心
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多