为什么ada中有if表达式和if语句,也for case
Why are if expressions and if statements in ada, also for case
摘自Introduction to Ada—If expressions:
Ada's if
expressions are similar to if
statements. However, there are a few differences that stem from the fact that it is an expression:
All branches' expressions must be of the same type
It must be surrounded by parentheses if the surrounding expression does not already contain them
An else
branch is mandatory unless the expression following then
has a Boolean value. In that case an else branch is optional and, if not present, defaults to else True
.
我不明白需要有两种不同的方式来构造带有 if
关键字的代码。这背后的原因是什么?
还有 case
表达式和 case
语句。这是为什么?
我认为最好通过引用 Ada 2012 基本原理来回答这个问题 Chapter 3.1:
One of the key areas identified by the WG9 guidance document [1] as
needing attention was improving the ability to write and enforce
contracts. These were discussed in detail in the previous chapter.
When defining the new aspects for preconditions, postconditions, type
invariants and subtype predicates it became clear that without more
flexible forms of expressions, many functions would need to be
introduced because in all cases the aspect was given by an expression.
However, declaring a function and thus giving the detail of the
condition, invariant or predicate in the function body makes the
detail of the contract rather remote for the human reader. Information
hiding is usually a good thing but in this case, it just introduces
obscurity. Four forms are introduced, namely, if expressions, case
expressions, quantified expressions and expression functions. Together
they give Ada some of the flexible feel of a functional language.
此外,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语句之外还有三元运算符?:
?
Egilhh 已经涵盖了主要原因,但有时还有其他有用的原因来实现表达式。有时你制作的包只需要一两个方法,而它们是制作包体的唯一原因。您可以使用表达式来创建表达式函数,从而允许您在规范文件中定义操作。
此外,如果您最终得到一些复杂的变体记录组合,有时可以使用表达式为它们设置默认值,以防您通常无法如此干净地设置它们。考虑以下示例:
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 想出两个单独命名的消息字段版本,当您希望代码映射到 ICD 时,这确实不是最佳选择。同样,我也可以使用一个函数来初始化它,但正如其他张贴者的回答中指出的那样,这并不总是一个好方法。
另一个概述了向 Ada 添加条件表达式的动机的地方可以在 ARG 文档中找到,AI05-0147-1,它解释了动机并给出了一些使用示例。
我发现它们非常有用的一个例子是处理命令行参数,如果在命令行上未指定参数,则使用默认值。通常,您希望在某个程序中将此类值声明为常量。条件表达式可以更轻松地做到这一点。
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;
...
摘自Introduction to Ada—If expressions:
Ada's
if
expressions are similar toif
statements. However, there are a few differences that stem from the fact that it is an expression:All branches' expressions must be of the same type
It must be surrounded by parentheses if the surrounding expression does not already contain them
An
else
branch is mandatory unless the expression followingthen
has a Boolean value. In that case an else branch is optional and, if not present, defaults toelse True
.
我不明白需要有两种不同的方式来构造带有 if
关键字的代码。这背后的原因是什么?
还有 case
表达式和 case
语句。这是为什么?
我认为最好通过引用 Ada 2012 基本原理来回答这个问题 Chapter 3.1:
One of the key areas identified by the WG9 guidance document [1] as needing attention was improving the ability to write and enforce contracts. These were discussed in detail in the previous chapter. When defining the new aspects for preconditions, postconditions, type invariants and subtype predicates it became clear that without more flexible forms of expressions, many functions would need to be introduced because in all cases the aspect was given by an expression. However, declaring a function and thus giving the detail of the condition, invariant or predicate in the function body makes the detail of the contract rather remote for the human reader. Information hiding is usually a good thing but in this case, it just introduces obscurity. Four forms are introduced, namely, if expressions, case expressions, quantified expressions and expression functions. Together they give Ada some of the flexible feel of a functional language.
此外,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语句之外还有三元运算符?:
?
Egilhh 已经涵盖了主要原因,但有时还有其他有用的原因来实现表达式。有时你制作的包只需要一两个方法,而它们是制作包体的唯一原因。您可以使用表达式来创建表达式函数,从而允许您在规范文件中定义操作。
此外,如果您最终得到一些复杂的变体记录组合,有时可以使用表达式为它们设置默认值,以防您通常无法如此干净地设置它们。考虑以下示例:
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 想出两个单独命名的消息字段版本,当您希望代码映射到 ICD 时,这确实不是最佳选择。同样,我也可以使用一个函数来初始化它,但正如其他张贴者的回答中指出的那样,这并不总是一个好方法。
另一个概述了向 Ada 添加条件表达式的动机的地方可以在 ARG 文档中找到,AI05-0147-1,它解释了动机并给出了一些使用示例。
我发现它们非常有用的一个例子是处理命令行参数,如果在命令行上未指定参数,则使用默认值。通常,您希望在某个程序中将此类值声明为常量。条件表达式可以更轻松地做到这一点。
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;
...