取自Introduction to Ada—If expressions:
Ada的
if
表达式类似于if
语句。但是,由于它是一个表达式,因此存在一些差异:所有分支的表达式必须具有相同的类型
如果周围的表达式尚未包含括号,则必须用括号将其括起来
除非在
else
之后的表达式具有布尔值,否则then
分支是必需的。在这种情况下,else分支是可选的,如果不存在,则默认为else True
。
我不明白需要使用两种不同的方式来使用if
关键字构造代码。这背后的原因是什么?
还有case
个表达式和case
条语句。为什么会这样?
答案 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;
...