通过合同编程时,函数或方法首先检查其前提是否已满足,然后才开始履行其职责,对吗?两个最重要的方式做这些检查是通过assert和exception.
你觉得哪一个更好?
请参阅此处的相关问题
当数组中元素的顺序不重要或甚至可能发生变化时,断言两个对象数组相等的好方法是什么?
有没有办法添加或编辑断言抛出的消息?我想用类似的东西
assert(a == b, "A must be equal to B");
Run Code Online (Sandbox Code Playgroud)
然后,编译器添加行,时间等...
可能吗?
你能举个例子static_assert(...)来优雅地解决问题吗?
我熟悉运行时assert(...).我什么时候应该static_assert(...)比常规更喜欢assert(...)?
此外,boost有一个叫做的东西BOOST_STATIC_ASSERT,它是一样的static_assert(...)吗?
一个声明,检查某些内容是否为真,如果没有则打印给定的错误消息并退出
这里有四个简单的assert调用:
>>> assert 1==2
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AssertionError
>>> assert 1==2, "hi"
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AssertionError: hi
>>> assert(1==2)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AssertionError
>>> assert(1==2, "hi")
Run Code Online (Sandbox Code Playgroud)
请注意,最后一个不会引发错误.调用带或不带括号的断言会导致这种行为有什么区别?我的做法是使用括号,但上面的建议我不应该这样做.
我想在我的Android应用程序中使用Assert关键字在某些情况下在模拟器或测试期间的设备上销毁我的应用程序.这可能吗?
似乎模拟器只是忽略了我的断言.
同事已经在我们的库中添加了几次assert命令,在那里我将使用if语句并抛出异常.(在此之前我从未听说过断言.)以下是他如何使用它的一个例子:
assert('isset($this->records); /* Records must be set before this is called. */');
Run Code Online (Sandbox Code Playgroud)
我会做的:
if (!isset($this->records)) {
throw new Exception('Records must be set before this is called');
}
Run Code Online (Sandbox Code Playgroud)
通过在assert上阅读PHP文档,看起来建议您确保assert处于活动状态并在使用assert之前添加处理程序.我找不到他这样做的地方.
所以,我的问题是,鉴于上述情况,使用断言是一个好主意,我应该更频繁地使用它而不是if和例外吗?
另外,我们计划在各种项目和服务器上使用这些库,包括我们甚至可能不参与的项目(库是开源的).这在使用assert时有什么不同吗?
我在以下代码段中有两个相同的字节数组:
/// <summary>
///A test for Bytes
///</summary>
[TestMethod()]
public void BytesTest() {
byte[] bytes = Encoding.UTF8.GetBytes(Properties.Resources.ExpectedPacketData);
TransferEventArgs target = new TransferEventArgs(bytes);
byte[] expected = Encoding.UTF8.GetBytes(Properties.Resources.ExpectedPacketValue);
byte[] actual;
actual = target.Bytes;
Assert.AreEqual(expected, actual);
}
Run Code Online (Sandbox Code Playgroud)
两个数组都是相同的字节.在这种情况下,为什么Assert.AreEqual会失败?
我倾向于在我的C++代码中添加许多断言,以便在不影响发布版本性能的情况下简化调试.现在,assert是一个纯C宏设计,没有考虑到C++机制.
另一方面std::logic_error,C++定义了在程序逻辑中存在错误(因此名称)的情况下抛出的内容.抛出一个实例可能只是一个完美的,更多的C++替代品assert.
问题是,assert并且abort两者都立即终止程序而不调用析构函数,因此跳过清理,而手动抛出异常会增加不必要的运行时成本.解决这个问题的一种方法是创建一个自己的断言宏SAFE_ASSERT,它就像C对应物一样工作,但在失败时抛出异常.
我可以想到关于这个问题的三种看法:
#define在C++中使用s同样糟糕.NDEBUG这种情况在发布版本中永远不会发生.捕获是不必要的,并公开内部代码的实现细节main().这个问题有明确的答案吗?有专业的参考吗?
编辑:跳过析构函数当然没有未定义的行为.
assert ×10
c++ ×3
php ×2
unit-testing ×2
android ×1
assertions ×1
c# ×1
c++11 ×1
coding-style ×1
debugging ×1
exception ×1
parentheses ×1
phpunit ×1
python ×1
r ×1