所有其他答案都捍卫了讲师的规则 3。
让我说我同意你的观点:这条规则是多余的,我不会建议它。确实,如果您总是添加大括号,它理论上可以防止错误。另一方面,我在现实生活中从未遇到过这个问题:与其他答案所暗示的相反,一旦有必要,我就没有忘记添加大括号。如果您使用适当的缩进,很明显您需要在多个语句缩进时添加大括号。
“组件 10”的答案实际上突出了唯一可能真正导致错误的情况。但另一方面,无论如何,通过正则表达式替换代码总是需要非常小心。
现在让我们看看奖牌的另一面:总是使用大括号有什么缺点吗?其他答案只是忽略了这一点。但是有一个缺点:它占用了大量的垂直屏幕空间,这反过来又会使您的代码不可读,因为这意味着您必须滚动超出必要的范围。
考虑一个开头有很多保护子句的函数(是的,以下是糟糕的 C++ 代码,但在其他语言中这将是很常见的情况):
void some_method(obj* a, obj* b)
{
if (a == nullptr)
{
throw null_ptr_error("a");
}
if (b == nullptr)
{
throw null_ptr_error("b");
}
if (a == b)
{
throw logic_error("Cannot do method on identical objects");
}
if (not a->precondition_met())
{
throw logic_error("Precondition for a not met");
}
a->do_something_with(b);
}
这是可怕的代码,我强烈认为以下代码更具可读性:
void some_method(obj* a, obj* b)
{
if (a == nullptr)
throw null_ptr_error("a");
if (b == nullptr)
throw null_ptr_error("b");
if (a == b)
throw logic_error("Cannot do method on identical objects");
if (not a->precondition_met())
throw logic_error("Precondition for a not met");
a->do_something_with(b);
}
同样,短嵌套循环也受益于省略大括号:
matrix operator +(matrix const& a, matrix const& b) {
matrix c(a.w(), a.h());
for (auto i = 0; i < a.w(); ++i)
for (auto j = 0; j < a.h(); ++j)
c(i, j) = a(i, j) + b(i, j);
return c;
}
与之比较:
matrix operator +(matrix const& a, matrix const& b) {
matrix c(a.w(), a.h());
for (auto i = 0; i < a.w(); ++i)
{
for (auto j = 0; j < a.h(); ++j)
{
c(i, j) = a(i, j) + b(i, j);
}
}
return c;
}
第一个代码简洁;第二个代码臃肿。
是的,可以通过将左大括号放在前一行来在一定程度上缓解这种情况。所以:如果你坚持使用花括号,至少把左大括号放在前一行。
简而言之:不要编写占用屏幕空间的不必要的代码。
自从最初编写答案以来,我大多接受流行的代码样式并使用大括号,除非我可以将整个单个语句放在前一行。我仍然认为不使用冗余大括号通常更具可读性,而且我仍然从未遇到过由此引起的错误。