TL;DR:
它没有特殊优势,但对于允许块声明的任何语言来说都是必要的一部分。
Ada的块终止方法非常明确,但这并没有传达任何特定的优势。
Discussion
正如其他人所指出的那样,这只是Ada的块终止方法。 语法细节并不是非常重要,但语义至关重要。
考虑一些其他语言中如何表达块终止的示例:
- Erlang和Prolog:lambda和条件语句使用关键字
end
,函数定义使用句点字符.
,短语分隔使用逗号,
和分号;
。
- Python、YAML、缩进模式的Haskell和RyuQ:块终止使用缩进(语义空格)。
- Ruby和Elixir:块终止使用关键字
end
。与Ada非常相似。
- Algol和sh/Bash/Dash:使用匹配反转的起始关键字来表示块终止。因此,
if
以fi
结束,case
以esac
结束。
- Rust、C、C++、D、Java、JavaScript/ECMA Script等:所有块都使用关键字和开放括号
{
打开,并使用关闭}
关闭所有块,这使得块的关闭标记可以轻松地被识别(由相对简单的解析器,而不一定是人类读者)。
- Lisp及其衍生语言:一般来说,所有表达式都是列表形式的语义表达式,并且所有评估块都使用
(
打开(这基本上意味着“开始评估”),而列表则使用'(
打开(这基本上意味着“我是一个列表,但跳过对我的评估”),并且所有列表都使用闭合括号)
关闭。
- XML、HTML、SGML、XSLT和其他令人噩梦的标记语言:每个(可能是任意的)开放标记,如
<foo>
,都由带有结束斜杠指示符的匹配标记终止,如</foo>
(或者有时只是</>
,出于重要原因,稍微好一点)。大多数变种的尖括号狂热现在也支持“自关闭”标记,其中关闭斜杠可以存在于开放标记的末尾作为缩写,因此像<foo></foo>
这样的空标记可以缩短为<foo />
或者有时取决于它所属的疯狂类型<foo/>
。(显然,这种模棱两可的语义黑洞有一些可能会吸引你。)
我們可以看到,Ada的塊終止表達式並不奇怪 - 它只是比方括號語言更明確(略微比Erlang和Prolog更明確)。無論如何,為了不使用GOTO或其他形式的顯式跳轉表達式,絕對有必要能夠定義邏輯塊,這也意味著必須有一種清晰的終止它們的方式。這就是Ada的方式。
附錄:關於“塊”的說明
正如flyx所指出的,語句、塊、表達式、過程、子程序和函數之間有一個有趣的區別。一些語言擁有所有這些,一些只有函數和表達式,一些則具有任意混合。
C(及其後代)區分“語句”和“表達式”,在由{}大括號界定的C風格塊的情況下,該“塊”被視為單個語句。這意味著,它不會像表達式那樣返回值,而是期望表示語句本身的過程執行對程序產生某些有意義的影響。
那在語法上意味著什麼?
在Ada中,if明確地打開一個塊。
在C语言中,
if
语句并不会打开或声明任何东西——它只是简单地保护下一条语句。因此,在C语言中看到单行的
if
语句是很正常的——不需要关闭任何括号,因为没有打开。但是,如果
if
语句后面的语句需要是多行语句(请注意,在C语言中为每个多行语句定义函数有点不符惯例)。
if (x) {do_something();}
是同样的意思
if (x) do_something();
看,妈妈,没有括号!
前者更常见,因为大多数条件分支不止一行。
这个特定问题变得有点模糊(现在你实际上涉及到分支预测问题)与C ternary operator:
int opening_time = (day == SUNDAY) ? 12 : 9
或者Python最近添加的三元运算符:
opening_time = 12 if day == 'sunday' else 9
一个等价的(在某种程度上不太习惯的 C 语言):
int opening_time = 9
if (day == SUNDAY) opening_time = 12
等等就是这样。
这里我们开始理解一些早期未命名代码块的实用性,并且了解在一些(但不是全部)编程语言中它们如何被视为复合语句。
if
块,使用字符(例如{
和}
)来界定块,或者具有等效于end if
的东西。 - Faibbus