代码之家  ›  专栏  ›  技术社区  ›  Canavar

断言编程的好处

  •  7
  • Canavar  · 技术社区  · 15 年前

    在代码中加入断言有什么意义?断言编程的好处是什么?

    private void WriteMessage(string message)
    {
        Debug.Assert(message != null, "message is null");
    
        File.WriteAllText(FILE_PATH, message);
    }
    

    例如,我们可以检查消息变量并在此处引发异常。为什么在这里使用断言?或者这是一个错误的例子来看待断言的好处?

    7 回复  |  直到 7 年前
        1
  •  9
  •   Shane Fulmer Lasse V. Karlsen    15 年前

    他们也支持快速失败的理念,解释说 this article Jim Shore。

        2
  •  7
  •   Tim Post Samir J M Araujo    15 年前

    有些人会写:

    /*
     * This can never happen
     */
    

    写作更实际:

    assert(i != -1);
    

    我喜欢使用断言,因为它们很容易被一个简单的编译时常量关闭,或者被用来做其他事情,比如准备一个错误报告。我通常不会在发布某些东西时打开断言(至少,不是通常的方式)。

    使用它们使我免于在别人的电脑上犯愚蠢的错误。那些喜欢测试我的字母代码的勇敢的灵魂。使用它们加上像Valgrind这样的工具有助于确保在提交之前捕获到可怕的东西。

        3
  •  2
  •   Rob Scott    15 年前

    需要考虑的一个重要区别是,您希望通过断言捕获哪些类型的错误。我经常使用断言来捕获编程错误(例如,使用空参数调用方法)和处理验证错误的不同机制(例如,传入错误长度的社会保障号码)。对于断言捕获的编程错误,我希望快速失败。对于验证错误,我希望响应不那么激烈,因为数据中可能存在错误是正常的(例如,用户执行某种类型的数据输入)。在这些情况下,正确的处理方法可能是将错误报告给用户并继续运行。

        4
  •  1
  •   Peter Perháč    15 年前

    如果该方法有一个指定的前置条件来获取非空消息参数,那么您希望程序在前置条件不存在时失败,然后必须修复bug的来源。

    我相信在开发安全关键软件时断言更重要。当然,您更愿意在正式指定软件时使用断言。

        5
  •  1
  •   JayMcClellan    15 年前

    对于断言(以及与代码构造相关的许多其他主题)的出色讨论,请查看 Code Complete 史蒂夫·麦康奈尔。他花了整整一章来有效地使用断言。

        6
  •  1
  •   MikeJ    15 年前

    我使用它们来验证是否提供了有效的依赖类。对于构造函数DI中的exmaple,您通常接受某种您依赖的外部类来提供一些操作或服务。

    所以你可以断言(classref!-空,“ClassRef不能为空”);而不是等待您将消息传递给ClassRef并获取一些其他异常,例如异常:访问冲突或同样不明确的东西,这些东西可能不会立即从代码中明显地看到。

        7
  •  0
  •   KRoy    7 年前

    测试我们的假设是非常有用的。断言不断地确保不变量为真。简而言之,它用于以下目的:

    • 它允许实现 快速失效 系统。
    • 减少错误传播 因为副作用。
    • 它禁止系统由于用户数据或随后的代码更改而进入不一致的状态。

    有时,当我们不想使用try/catch/throw时,我倾向于使用assert_return()。

    private void WriteMessage(string message)
    {
        assert_return(message != null, "message is null"); // return when false
        File.WriteAllText(FILE_PATH, message);
    }
    

    我建议通过报告测试构建中的错误来终止应用程序。然后在生产系统中,它应该记录和错误,并从函数返回,表示它不能这样做。