我正在重构一些充满ASSERT语句的MFC代码,为了准备未来的Linux端口,我想用标准替换它们assert.人们知道的两种实现之间是否有任何重大差异可能会让我感到困惑?
同样,我也遇到了一些ATLASSERT我想要替换的代码.
断言用于检查是否满足条件(前置条件,后置条件,不变量),并帮助程序员在调试阶段找到漏洞.
例如,
void f(int *p)
{
assert(p);
p->do();
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我们是否需要假设在发布模式下无法满足条件并相应处理案例?
void f(int *p)
{
assert(p);
if (p)
{
p->do();
}
}
Run Code Online (Sandbox Code Playgroud)
毕竟,断言意味着它所测试的条件永远不应该是假的.但是,如果我们不检查它并且它失败了,程序崩溃了.听起来像是两难.你们怎么处理它?
由于Matlab被解释,通常会在执行函数签名的函数开头花费大量时间.例如
if nargin ~= 2; error('must provide two input args a and b'); end
if a < 0||a ~=floor(a); error('input arg1 must be positive non-zero integer'); end
if ~isa(b,'cell') ...
Run Code Online (Sandbox Code Playgroud)
相反,使用Matlab的assert()会更好吗?如果没有,何时适合在Matlab中使用assert()?
有对在生产中使用代码断言的大讨论在这里,但我不能肯定这适用于解释的代码.同样,这里有另一个很好的讨论,我同意@Dan Dyer关于断言表达对当前状态的看法.然而,在这里看一下类似的Python讨论人们说,只使用断言来应对永远不会发生的情况(例如异常情况的异常),这与之前的引用有点矛盾.
也许这更像是一个关于断言在解释语言中扮演的角色的问题,而不是关于Matlab的问题.
在工作中,我遇到了这种方法,它困扰着我。事实上,方法的名称、文档和实现并没有真正相互匹配(并且传递 true 使 true 的条件变为 false),我不明白拥有这样一个方法的意义(这是生产代码):
# @brief An utility method that raises if the singleton is not in a good
# state
#@param expect_instanciated bool : if True we expect that the class is
# allready instanciated, else not
# @throw RuntimeError
@classmethod
def singleton_assert(cls, expect_instanciated=False):
if expect_instanciated:
if not cls.started():
raise RuntimeError("The Settings class is not started yet")
else:
if cls.started():
raise RuntimeError("The Settings class is already started")
Run Code Online (Sandbox Code Playgroud)
以下是我的担忧:
我定期验证我的函数参数:
public static void Function(int i, string s)
{
Debug.Assert(i > 0);
Debug.Assert(s != null);
Debug.Assert(s.length > 0);
}
Run Code Online (Sandbox Code Playgroud)
当然,检查在函数的上下文中是"有效的".
这是常见的行业惯例吗?关于函数参数验证的常见做法是什么?
在方法中使用断言是不好的做法吗?
例如
def add(x, y):
assert isinstance(x, int) and isinstance(y, int)
return x + y
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
在设计一个类时,应该将逻辑维护有效状态合并到类中还是外部?也就是说,属性是否应该在无效状态上抛出异常(即值超出范围等),还是应该在构造/修改类的实例时执行此验证?