因此,在大多数编程语言中,如果使用循环或if,如果只有一个语句,则可以不使用花括号,例如:
if (true)
//Single statement;
for (int i = 0; i < 10; i++)
//Single Statement
while (true)
//Single statement
但是,它不适用于函数,例如:
void myFunction()
//Single Statement
所以,我的问题,为什么它不能用于函数?
答案 0 :(得分:8)
C ++需要它来消除一些结构的歧义:
void Foo::bar() const int i = 5;
const
现在属于bar
还是i
?
答案 1 :(得分:5)
因为语言语法禁止你这样做。
Java语法定义了如下方法:
MethodDeclaration:
MethodHeader MethodBody
Methodbody as:
MethodBody:
Block
;
这意味着Block(见下文)或单个分号
Block:
{ BlockStatementsopt }
一个块作为大括号内的一个或多个语句。
但if定义为:
IfThenStatement:
if ( Expression ) Statement
在结束后不需要阻止的情况下,因此单行就可以了。
为什么他们选择这样定义?人们只能猜测。
语法可以在这里找到:http://docs.oracle.com/javase/specs/jls/se7/html/index.html
答案 2 :(得分:4)
这不是一个规则,在某些语言中你可以(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!";}}}
奇怪的是,它变得有些可理解。
实际问题不是可读性(无论如何关心?我当然是在开玩笑)但在后者:理解。您不仅必须能够理解代码 - 编译器必须。对于编译器来说,没有&#34;哦,这看起来像函数&#34;。编译器必须绝对确定它是一个函数。此外,它必须完全确定它的起始位置,结束位置,等等。而且必须这样做而不要过多地查看空格,因为C系列语言允许您以任意数量添加它们。
所以,让我们再看看打包的无支撑示例
namespace Example class Foo : public Bar public : std::string myMethod() return "Oh noes!";
^ ^ ^^
我标记了一些有问题的符号。假设你可以定义一个处理它的语法,请注意&#34;的含义:&#34;性格变化。有一段时间它表示你正在指定继承,另一方面它指定了一个方法的访问修饰符,在第三方面它只是命名空间限定符。好吧,如果你很聪明,可以放弃第三个,并注意到它实际上是&#39; ::&#39;符号,而不只是&#39;:&#39;字符。
此外,关键字的含义可能会发生变化:
namespace Example class Foo : public Bar public : std::string myMethod() return "Oh noes!";
^^^^^^ ^^^^^^
首先,它为继承的基类定义访问修饰符,在第二个位置定义了方法的访问修饰符。更重要的是,首先它的并不意味着后面跟着&#34;:&#34;在第二个地方,它必须被它跟随!
如此多的规则,例外和极端案例,我们只涉及两个简单的事情:公共和&#39;:&#39;。现在,想象一下你要指定整个语言的语法。你用你想要的方式描述一切。但是,当你将所有规则收集在一起时,它们在某些时候可能会重叠并相互碰撞。添加第N个规则后,可能会发生您的编译器&#39;我们无法判断公众是否会这样做。实际上标记了继承,或者启动了一个方法:
namespace Example class Foo : public ::Bar public : std::string myMethod() return "Oh noes!";
^^^^^^^^ ^^^^^^^^
请注意,我只将Bar
更改为::Bar
。我只添加了一个命名空间限定符,现在我们的&#34; public的规则之后是冒号&#34;被摧毁了。由于我现在添加了一个规则,即&#34;基类名称可能具有命名空间限定符&#34;,我还必须添加更多规则来覆盖另一个极端情况 - 消除&#34; public&#34含义的模糊性;和&#34;:&#34;在这个地方。
减少冗长的话题:规则越多,问题越多。 &#34;编译器&#34;成长,变慢,吃更多的资源来工作。这导致无法处理大型代码文件,或者当用户必须等待该模块进行编译时才会感到沮丧。
但对于用户来说更糟糕的是,更糟糕的错误消息越复杂或越模糊。没有人想使用无法解析某些代码的编译器,也无法告诉你它有什么问题。
请记住,在C ++中,当你忘记了一些&#39 ;;&#39;在.h
文件中?或者当你忘记一些}
时?编译器报告错误30或300行更远。这是因为&#39 ;;&#39;和&#39; {}&#39;可以在许多地方省略,对于30或300行,编译器根本不知道错误!如果在任何地方都需要括号,可以更快地确定错误点。
另一种方式:在命名空间,类或函数级别使它们可选,将删除基本的块开始/块结束标记,至少:
任何人都不想要的任何部分。
C ++语法非常复杂,实际上根本不可能省略那些地方的大括号。对于Java或普通的C,我认为可以创建一个不需要它们的语法/编译器,但是它仍然会损害错误报告。特别是在允许使用#include
和宏的C中。在早期的Java中,影响可能会更小,因为语法相对简单,比较当前的C ++ ..
可能最简单,最快速,最容易实现,也许最容易学习的语法......需要几乎无处不在的大括号(或任何其他分隔符)。例如,检查LISP。但是,你的大部分工作将包括不断编写相同的必需标记,许多语言用户根本不喜欢(即当我需要在VisualBasic中使用&#34处理一些旧代码时,我会感到恶心;如果然后结束,如果&#34; yuck)
现在,如果你看一下像Python这样的无支撑语言 - 他们如何解决它?它们通过......意图来表示块开始/块结束。使用此语言,您必须正确缩进代码。如果你没有正确地缩进它,它根本就不会编译,或者循环/函数/等会默默地让它们的代码弄乱,因为编译器不会知道哪个部分属于哪个范围。再没有免费午餐。
答案 3 :(得分:1)
基本上,方法(函数)是一组语句,它们组合在一起以执行操作。我们将语句分组为可重用的。也就是说,如果您知道在这种情况下将经常使用一组指令,我们将其创建为单独的函数。
如果您可以在一行代码中执行任务,那么为什么需要编写函数?
答案 4 :(得分:0)
没有理由在编译器中添加额外的解析代码,因为功能真的没用,你编写了多少个不是访问器或者mutator的一行方法?这已在C#中通过属性处理,但尚未在Java中处理。
所以原因是,考虑到大多数开发人员不鼓励遗漏可选的支架块,它不太可能被使用。
答案 5 :(得分:0)
因为语言的语法不允许你这样做。
以下是取自ISO / IEC 9899-1999规范的C函数的语法:
6.9.1 Function definitions
Syntax
1 function-definition:
declaration-specifiers declarator declaration-listopt compound-statement
复合语句部分是函数体,复合语句声明为
compound-statement:
{ block-item-listopt }
即。它以大括号开始和结束。
if
,while
或类似机构的身体可以statement
。
(6.8.5) iteration-statement:
while ( expression ) statement
声明可以是几种结构之一。
statement:
labeled-statement
compound-statement
expression-statement
selection-statement
iteration-statement
jump-statement
其中只有compound-statement
需要大括号。
答案 6 :(得分:0)
你无法准确地说C#中没有一个语句功能。匿名方法可能就是其中之一。如果没有单行语句,我们就无法在c#中使用Lambda表达式。 C#3.0不会存在。
答案 7 :(得分:0)
在c ++中,你需要一个复合语句来创建一个函数体 - 它实际上是用花键围绕的。这并不意味着你需要立即拥有大括号,下面将编译得很好:
int foobar()
try {
return 1;
}
catch (...){return 0;}