与其他语言相比,Ada 中的 end if 语句有什么优势

What advantage does the end if statement in Ada provide over other languages

大多数其他编程语言在条件语句末尾不需要 end if 语句。

if boolean_expression then statement else statement

包含 end if 的 Ada 有什么优势是其他语言所没有的?

if boolean_expression then statement else statement end if

我认为它与条件为真时的分支预测有关(跳过代码的 else 部分),但我不确定。

考虑一个嵌套的 if,像这样:if boolean_expression then if another_boolean_expression then statement else statement

现在,else 部分属于哪个 if 语句?

end if 解决了问题(为清楚起见缩进):

if boolean_expression then 
   if another_boolean_expression then
      statement 
   end if;
else
  statement 
end if;

或:

if boolean_expression then 
   if another_boolean_expression then
      statement
   else
      statement
   end if;
end if;

长话短说:

它没有什么特别的优势,但它是任何允许块声明的语言的必要组成部分。

Ada 的块终止方法非常明确,但这并没有传达任何特别的优势。

讨论

正如其他人所指出的,这只是 Ada 的块终止 方法。 语法细节不是很重要,但语义很关键。

考虑几个如何用其他语言表达块终止的例子:

  • ErlangProlog:lambdas和条件语句的关键字end,句号. 用于函数定义,,; 用于短语分离。
  • Python, YAML, "缩进模式" Haskell and RyuQ: 块终止用缩进(语义空白)表示。
  • RubyElixir:块终止用关键字end表示。和阿达很像。
  • Algolsh/Bash/ Dash:快速块终止与启动关键字的匹配反转。所以 iffi 结束,而 caseesac 结束。
  • Rust, C, C++, DJavaJavaScript/ECMA Script 等:全部使用关键字和左括号 { 并用结束符 } 关闭所有块,这样可以轻松识别块的结束标记(通过相对幼稚的解析器,不一定是人类 reader)。
  • Lisp 和朋友们:一般来说,一切都是列表形式的语义表达,所有求值块都以 ( 打开(本质上意味着“开始求值” ") 而列表以 '( 打开(这实际上意味着“我是一个列表,但跳过评估我”)并且所有列表都以右括号 ).
  • 关闭
  • XML, HTML, SGML, XSLT,以及其他醒着的噩梦:每个(可能是任意的)开始标签,如 <foo> 都由一个带有结束斜线指示符的匹配标签终止,如 </foo>(或者有时只是</>,由于重要原因,它稍微好一点)。尖括号疯狂的大多数变体现在也支持“自闭”标签,其中结束斜线可以作为 shorthand 存在于开始标签的末尾,因此空标签是它自己的短语,如 <foo></foo> 可以缩短为 <foo /> 或有时 <foo/> 取决于它恰好是什么精神错乱的味道。 (显然,有 a few semantic black holes 人会被这种模棱两可的事情所吸引。)

等等...

正如我们所见,Ada 的块终止表达式一点也不奇怪——它只是比方括号语言更明确(比 Erlang 和 Prolog 稍微更明确)。无论如何,在不求助于 GOTO 或其他形式的显式跳转表达式的情况下,绝对有必要能够定义逻辑块,这也意味着有一种明确的方式来终止它们。这只是 Ada 的方式。

附录:关于“块”的注释

正如 flyx 所指出的,语句、块、表达式、过程、子例程和函数之间存在有趣的区别。有些语言拥有所有这些,有些只有函数和表达式,有些有任意组合。

C(及其后代)区分“语句”和“表达式”,在由 {} 大括号分隔的 C 风格块的情况下,语言将“块”视为“块”作为单个语句。意思是,它是 而不是 预期 return 一个表达式的值,预计由语句本身表示的过程的执行将对程序。

那么这在语法方面意味着什么?

在 Ada 中 if 明确地 打开一个块

然而,在 C 中,if 根本不打开或声明任何东西 -- 它只是 保护下一个语句。因此,在 C 语言中,一行 if 是完全正常的——根本不需要关闭括号,因为 none 被打开了。但是,如果 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;

以此类推

在这里我们可以了解未命名代码块的一些早期实用程序,以及在某些(但不是所有)语言中它们如何被视为 复合语句.

Ada 语言的设计考虑了可读性和代码缺陷预防。因此,范围关闭结构是强制性的,并且对应于范围开放结构。当您有一段很长的代码时,会更容易弄清楚关闭条目实际上关闭了什么。

procedure Foo is
begin
    if condition then 
    -------------------
    -- a lot of code...
    -------------------
    end if;
end Foo;

相比之下,一些其他语法不同的语言可能会让开发人员自行决定是编写额外的注释来阐明关闭条目的目的,还是根本不编写关闭条目(C++ 示例):

void
Foo(void)
{
    if(condition)
    {
    ///////////////////
    // a lot of code...
    ///////////////////
    } // if
} // Foo

这样的代码变得可读性较差并且可能容易出现范围问题,或者需要开发人员付出额外的努力。