任何人都可以给我一个Ada中"单引号"用法的摘要?

mil*_*sma 5 arguments record ada new-operator quote

我刚读过"Ada Programming",但我对如何'在Ada中使用(单引号)感到困惑.

我可以理解,'它用于引用属性.AAA'Image(..),BBB'Value(..)

但是,考虑到这段代码:

   type Plain_Vector (Capacity : Capacity_Subtype) is record
      Elements : Elements_Array (1 .. Capacity);
      Last     : Extended_Index := No_Index;
      Busy     : Natural := 0;
      Lock     : Natural := 0;
   end record;
 ------------------------------------------------------------------
   new Plain_Vector'(2, (Left, Right), Last => Last, others => <>)
Run Code Online (Sandbox Code Playgroud)

Q1: "new"语句的参数如何与类型的参数和记录字段匹配?

 I can GUESS "2" matched "Capacity", 
             "(Left, Right)" matched "Elements", 
             "Last => Last" matched "Last"
             "Others => <>" matched "Busy" and "Lock" to let them use default value.
Run Code Online (Sandbox Code Playgroud)

但这只是一个GUESS,对此有任何官方语法解释吗?

Q2:这是'做什么的?(在"新"声明中)

它是属性还是有任何其他含义?

我在哪里可以找到Ada中"单引号"的摘要用法

我花了很长时间试图找出这些信息,但没有运气.

先感谢您.万里.

Kei*_*son 7

如果您有Ada参考手册的软拷贝,您可以'在语法摘要中搜索该字符(我在最新版本中附件P;查看目录).

'角色用于:

  • 字符文字: 'x'
  • 属性参考: Foo'Size
  • 合格表达式:Some_Type'(expression),Some_Type'Aggregate

它也用在表示子句中(现在称为"aspect子句"); 这看起来很像属性引用:for Foo'Size use 32;.

当然,它可以出现在注释中,也可以出现在字符串或字符文字中.

您发布的代码中的示例是一个限定表达式.

建议:在字符文字以外的上下文中,字符'应该被称为撇号,因为它不作为引号.对于属性和限定表达式,它有时发音为"tick":我读Foo'Size作"foo tick size".

(并且new是表达,而不是声明.)


T.E*_*.D. 5

您似乎专门询问合格的表达式(Keith 在他的回答中的第三个要点)。

在 Ada 中,如果您有两个不同类型的对象,您可以尝试使用目标类型的名称(如函数名称)在它们之间进行转换,如下所示:

Foo : 常量 Integer := Integer (2.35);

通常,这只适用于两种类型都是数字类型,或者一种派生自另一种(声明为type New_Type is new Old_Type...)。

编译器当然必须添加代码来验证该值是否在目标类型可能具有的任何约束范围内。但这对于简单的类型转换非常有用。

但是,当您处理表达式时,有时您想要的不是转换,而是告诉编译器生成表达式的类型。不需要(运行时)代码来执行此操作,只需将表达式设为我告诉您的类型即可。

编译器通常可以从上下文中弄清楚这一点,但有时他们不能。这就是撇号的用武之地。它告诉编译器不要表达式转换为指定的类型,而是首先将其创建为该类型。

最常见的用途是执行动态分配时,如您的示例所示。有时可能还有其他情况需要它。一个例子可能是将文字值传递到重载例程中。假设您有两个版本的过程My_Routine,一个接受 an Integer,另一个接受不同的自定义整数类型。如果您将对象传递给它,编译器可以只查看对象的类型。然而,如果你传入一个字面量1,很可能你会得到一个编译器错误,表示表达式不明确。

您可以通过将您的文字1放入一个常量整数并将其传入(然后抱怨您的愚蠢编译器)来解决此问题。但是,更简单的做法是:

My_Routine (Integer'(1));
Run Code Online (Sandbox Code Playgroud)

这解决了编译器的歧义。这不是“转换”,因此不需要额外的代码。您只是告诉编译器以下表达式的类型Integer