为什么在ada中使用if表达式和if语句,也用于大小写

时间:2019-04-26 04:45:48

标签: if-statement ada

取自Introduction to Ada—If expressions

  

Ada的if表达式类似于if语句。但是,由于它是一个表达式,因此存在一些差异:

     

所有分支的表达式必须具有相同的类型

     

如果周围的表达式尚未包含括号,则必须用括号将其括起来

     

除非在else之后的表达式具有布尔值,否则then分支是必需的。在这种情况下,else分支是可选的,如果不存在,则默认为else True

我不明白需要使用两种不同的方式来使用if关键字构造代码。这背后的原因是什么?

还有case个表达式和case条语句。为什么会这样?

3 个答案:

答案 0 :(得分:5)

我认为最好引用Ada 2012基本原理Chapter 3.1

  

WG9指导文件[1]确定的关键领域之一是   需要注意的是提高编写和执行的能力   合同。这些已在上一章中详细讨论过。   在定义前提条件,后置条件,类型的新方面时   不变式和子类型谓词很明显,没有更多内容   灵活的表达式形式,很多功能都需要   之所以进行介绍,是因为在所有情况下,方面都是由表达式给出的。   但是,声明一个函数,从而提供详细信息   功能主体中的条件,不变或谓词使   对于人类读者而言,合同的细节相当遥远。信息   隐藏通常是一件好事,但在这种情况下,它只是引入了   朦胧。引入了四种形式,即表达式,大小写   表达式,量化表达式和表达式函数。一起   他们为Ada带来了一种功能语言的灵活感觉。

此外,if语句和case语句通常在所有分支中为同一变量分配不同的值,而没有其他任何东西:

if Foo > 10 then
   Bar := 1;
else
   Bar := 2;
end if;

在这种情况下,if表达式可以提高可读性,并在代码中更清楚地说明正在发生的事情:

Bar := (if Foo > 10 then 1 else 2);

我们现在可以看到,代码的维护者不再需要读取整个if语句,从而只需更新一个变量即可。

case表达式也是如此,这也可以减少嵌套if表达式的需要。

此外,我可以将问题抛给您:为什么基于C的语言除了if语句外还具有三元运算符?:

答案 1 :(得分:3)

Egilhh已经介绍了主要原因,但是有时还有其他有用的理由来实现表达式。有时,您在只需要一种或两种方法的情况下制作软件包,这是制作软件包正文的唯一原因。您可以使用表达式来创建表达式函数,以便您可以在spec文件中定义操作。

此外,如果最终遇到一些复杂的变体记录组合,有时在通常情况下无法使用整洁的情况下,可以使用表达式为它们设置默认值。考虑以下示例:

with Ada.Text_IO; use Ada.Text_IO;

procedure Hello is

    type Binary_Type is (On, Off);

    type Inner(Binary : Binary_Type := Off) is  record
        case Binary is
            when On =>
                Value : Integer := 0;
            when Off =>
                null;
        end case;
    end record;

    type Outer(Some_Flag : Boolean) is record
        Other : Integer := 32;
        Thing : Inner   := (if Some_Flag then 
                              (Binary => Off) 
                            else 
                              (Binary => On, Value => 23));
    end record;

begin
  Put_Line("Hello, world!");
end Hello;

我想出了一个更复杂的设置,该设置旨在映射到硬件级别的复杂消息传递接口。尽可能有默认值是很好的。现在,我冷漠地在Outer内部使用了一个case,但是随后我将不得不为每种case给出两个单独命名的message字段版本,当您希望代码映射到ICD时,这并不是最佳选择。同样,我也可以使用一个函数来对其进行初始化,但是正如其他张贴者回答所述,这并不总是一种好方法。

答案 2 :(得分:2)

可以在ARG文档AI05-0147-1中找到概述向Ada添加条件表达式的动机的另一个地方,该文档解释了动机并提供了一些使用示例。

在处理命令行参数时,我发现它们非常有用的一个例子,这是在未在命令行上指定参数的情况下使用默认值的情况。通常,您需要在程序中将这些值声明为常量。条件表达式使其更容易实现。

with Ada.Command_Line; use Ada;

procedure Main
is
   N : constant Positive :=
     (if Command_Line.Argument_Count = 0 then 2_000_000
      else Positive'Value (Command_Line.Argument (1)));
   ...

否则,如果没有条件表达式,则要获得相同的效果,您需要声明一个函数,我发现该函数更难以阅读;

with Ada.Command_Line; use Ada;

procedure Main
is

   function Get_N return Positive is
   begin
      if Command_Line.Argument_Count = 0 then
         return 2_000_000;
      else
         return Positive'Value (Command_Line.Argument (1));
      end if;
   end Get_N;

   N : constant Positive := Get_N;
   ...