为什么前缀调用不适用于访问类型?

Why don't prefixed calls work on access types?

我在一个包中有一些方法可以对标记记录的访问常量进行操作;为了调用这些函数,我必须指定包名。我更愿意只输入变量名 [dot] 函数名,但这给出了错误:no selector "foo" for type "Color"。这是为什么?

这是一个最小的复制器:

procedure Main is

  type Color is tagged
    record
      Hue : Integer;
      Saturation : Integer;
      Value : Integer;
    end record;

  type AccessColor is access constant Color;

  procedure foo (C : in AccessColor) is
  begin
    null;
  end foo;

  AccessS : AccessColor;

begin
  foo (AccessS);
  --AccessS.foo; -- does not work. Why?
end Main;

请注意,在我的真实代码中,不方便完整地指定函数,因为与上面的示例不同,foo 是在单独的包中的某个地方定义的:

Some.Package.Name.Depp.foo(AccessS);

尽管 AccessS 已经指定了在哪里可以找到函数,所以我应该能够做到:

AccessS.foo;

这不起作用,因为按照您的定义,foo 不是标记类型 Color 原始操作 。前缀表示法只能用于标记类型的原始操作。

解决方案是使 foo 成为 Color 的原始操作,如下所示:

procedure foo (C : access constant Color) is
begin
   null;
end foo;

如果您使用命名访问类型,foo 将改为该类型的原始操作,并且由于该类型不是标记类型,前缀表示法不起作用。

问题是 foo 实际上不是 Color 的原始操作(在这个复制器中)。

ARM 3.3.2(6)表示特定类型的原始子程序是

For a specific type declared immediately within a package_specification, any subprograms (in addition to the enumeration literals) that are explicitly declared immediately within the same package_specification and that operate on the type

这(对重新格式化、大小写调整表示歉意)编译正常。

procedure Main is

   package Pak is

      type Color is tagged
         record
            Hue : Integer;
            Saturation : Integer;
            Value : Integer;
         end record;

      procedure Foo (C : in Color) is null;

      type AccessColor is access constant Color;

   end Pak;

   Col : aliased Pak.Color;

   AccessS : Pak.AccessColor := Col'Access;

begin
   AccessS.Foo;
end Main;

我宣布 Foo 服用 in Color;如果需要,您同样可以声明它采用 access constant Color,因为 (ARM 4.1.3(9.2))

The first formal parameter of the subprogram shall be of type T, or a class-wide type that covers T, or an access parameter designating one of these types