这不是一个规则,在某些语言中你可以(Python?是的,我知道这确实是人为的例子:))),在其他语言中你不能。
您可以很好地将您的问题扩展到类和命名空间,例如,为什么不:
namespace Example
class Foo : public Bar
public: std::string myMethod()
return "Oh noes!";
对吗?在每个级别,这只是一个项目,所以为什么不到处跳过大括号呢?
答案既简单又复杂。
简单来说,就是可读性。请记住,您可以随意布局代码,因为空格通常会被编译器丢弃:
namespace Example class Foo : public Bar public: std::string myMethod() return "Oh noes!";
嗯,这开始看起来难以理解。请注意,如果您将大括号添加回来
namespace Example { class Foo : public Bar { public: std::string myMethod() {return "Oh noes!";}}}
然后奇怪的是,它变得有点可理解了。
真正的问题不在于可读性(谁在乎呢?我当然是在开玩笑),而在于后者:理解力。不仅您必须能够理解代码 - 编译器必须。对于编译器来说,没有“哦,这看起来像函数”这样的东西。编译器必须绝对确定它是一个函数。此外,它必须完全确定它从哪里开始,在哪里结束,等等。而且它必须做到这一点,而不需要过多地查看空格,因为 C 系列语言允许您添加任意数量的空格。
那么,让我们再看看打包的无括号示例
namespace Example class Foo : public Bar public : std::string myMethod() return "Oh noes!";
^ ^ ^^
我标记了一些有问题的符号。假设您可以定义处理它的语法,请注意“:”字符的含义如何变化。有时它表示您正在指定继承,有时它正在指定对方法的访问修饰符,第三次它只是命名空间限定符。好的,如果你很聪明并注意到它实际上是 '::' 符号,而不仅仅是一个 ':' 字符,则可以丢弃第三个。
另外,关键字的含义可以改变:
namespace Example class Foo : public Bar public : std::string myMethod() return "Oh noes!";
^^^^^^ ^^^^^^
首先,它为继承的基类定义访问修饰符,其次它为方法定义访问修饰符。更何况,第一个不应该后面跟一个“:”,第二个是必须跟它!
这么多规则、例外和极端情况,我们只介绍了 2 个简单的东西:public 和 ':'。现在,假设您要指定整个语言的语法。你用你想要的方式描述一切。但是,当您将所有规则聚集在一起时,它们在某些时候可能会开始重叠并相互冲突。添加第 N 条规则后,您的“编译器”可能无法判断“公共”是否真正标记了继承,或者启动了一个方法:
namespace Example class Foo : public ::Bar public : std::string myMethod() return "Oh noes!";
^^^^^^^^ ^^^^^^^^
请注意,我只将Bar 更改为::Bar。我只添加了一个命名空间限定符,现在我们的“公共后跟冒号”的规则被丢弃了。由于我现在添加了“基类名称可能具有命名空间限定符”的规则,因此我还必须添加更多规则以涵盖另一个极端情况 - 以消除此处“public”和“:”含义的歧义。
长话短说:规则越多,问题就越多。 “编译器”增长,变慢,消耗更多资源来工作。这会导致无法处理大型代码文件,或者当用户必须等待很长时间才能编译该模块时感到沮丧。
但对用户来说更糟糕的是,越复杂或模棱两可,错误消息就越糟糕。没有人愿意使用无法解析某些代码并且也无法告诉您它有什么问题的编译器。
记住在 C++ 中当你忘记一些 ';' 时会发生什么在.h 文件中?或者当您忘记一些} 时?编译器在 30 或 300 行之后向您报告错误。这是因为';'并且 '{}' 可以在很多地方省略,对于那 30 或 300 行,编译器根本不知道这是错误的!如果处处都需要大括号,则可以更快地查明错误点。
另一种方式:在命名空间、类或函数级别将它们设为可选,将删除基本的块开始/块结束标记,并且至少:
- 可能会使语法模棱两可(并因此强制添加更多规则)
- 可能会影响检测(和报告!)错误
没有人真正想要的任何部分。
C++ 语法非常复杂,实际上可能根本不可能在这些地方省略大括号。对于 Java 或纯 C,我认为可以制作一个不需要它们的语法/编译器,但它仍然会对错误报告造成很大的伤害。特别是在允许使用#include 和宏的C 语言中。在早期的 Java 中,影响可能较小,因为语法相对简单,与当前的 C++ 相比..
可能是最简单、最快、最容易实现并且可能最容易学习的语法……几乎在任何地方都需要大括号(或任何其他分隔符)。例如检查 LISP。但是,您的大部分工作将包括不断编写相同的必需标记,这是许多语言用户根本不喜欢的(即,当我需要在 VisualBasic 中使用“如果然后结束如果”来处理一些旧代码时,我会感到恶心“呸)
现在,如果你看看像 Python 这样的无括号语言 - 他们是如何解决这个问题的?它们通过 .. 意图表示块开始/块结束。在这种语言中,您必须正确缩进您的代码。如果你没有正确缩进它,它根本不会编译,或者循环/函数/等会默默地弄乱他们的代码,因为编译器不知道哪个部分属于哪个范围。这里又没有免费的午餐了。