什么时候应该使用断言和前置条件,何时可以使用保护语句,强制解包和错误处理?

时间:2017-02-24 15:48:43

标签: swift debugging error-handling assertions forced-unwrapping

我已经阅读了Difference between “precondition” and “assert” in swift。但仍然无法在(不同的展开方式,即guard& ! + 错误处理)与断言之间划清界线。

如果我希望我的应用程序不再起作用,我不能只强制打开一些东西并替换前提条件吗?

  1. 是因为我们希望 停止/退出应用程序,基本上不希望任何控制流或状态发生变化,因此我们使用也会发生的断言/先决条件轻松记录人类可读消息(帮助我们不要经常写print s)?
  2. 我们使用断言的东西是至关重要的,守护语句最终是一个控制流系统,即使你的函数提前返回也不一定意味着你的应用程序应该崩溃。
  3. 如果超出nil之类的任何内容,就像你想要一个 String 而用户正在给你一个 Int 那么你可以使用错误处理

    修改

    我不是在发表意见,我只是想要了解这些替代方案断言提供的便利性。编号列表是我问题的核心。

1 个答案:

答案 0 :(得分:3)

  • 错误是流量控制的一种形式,与ifwhile相同。特别是,它们涉及连贯的消息发送提前退出。我的想法是立即结束当前范围并将控制权交还给呼叫者,告诉呼叫者“出了问题”。

  • 断言是一种立即崩溃的方式。

因此,它们属于完全不同的概念世界。错误是针对可能实时出错的事情,我们需要通过它来连贯地恢复。断言是针对永远不会出错的事情,我们对此感到如此强烈以至于我们不希望程序在这些情况下被释放到世界中,并且可以在不能使用错误的地方使用。

我自己的代码示例:

final class Board : NSObject, NSCoding, CALayerDelegate {
    // ...
    fileprivate var xct : Int { return self.grid.xct }
    fileprivate var yct : Int { return self.grid.yct }
    fileprivate var grid : Grid // can't live without a grid, but it is mutable
    // ...
    fileprivate lazy var pieceSize : CGSize = {
        assert((self.xct > 0 && self.yct > 0), "Meaningless to ask for piece size with no grid dimensions.")
        let pieceWidth : CGFloat = self.view.bounds.size.width / (CGFloat(self.xct) + OUTER + LEFTMARGIN + RIGHTMARGIN)
        let pieceHeight : CGFloat = self.view.bounds.size.height / (CGFloat(self.yct) + OUTER + TOPMARGIN + BOTTOMMARGIN)
        return CGSize(width: pieceWidth, height: pieceHeight)
    }()
    // ...
}

如果使用零网格维度调用pieceSize ,那么我的整个程序就会出现问题。这不是测试运行时错误的问题;程序本身基于错误的算法。这就是我想要发现的。