【问题标题】:Why don't prefixed calls work on access types?为什么前缀调用不适用于访问类型?
【发布时间】:2019-09-17 09:22:10
【问题描述】:

我在一个包中有一些方法可以操作一个访问常量到一个标记记录;为了调用这些函数,我必须指定包名。我宁愿只输入变量名 [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。也可以使用in Color 来获得相同的结果。
  • 为什么要使用访问类型?他们几乎从来不需要。当然,这似乎不需要它们。

标签: ada


【解决方案1】:

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

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

对于在 package_specification 中立即声明的特定类型,在同一 package_specification 中立即明确声明并在类型

这(对于重新格式化,大小写调整表示歉意)编译良好。

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;

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

子程序的第一个形参应该是类型 T,或覆盖 T 的类范围类型,或指定这些类型之一的访问参数

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

    • 在更改函数定义以指定access constant Color作为参数后,我仍然在注释的用法行中得到相同的错误。
    • 您可能需要相应地定义AccessS。我不确定定义类型 AccessColor 是否会导致类型冻结——这不应该发生,但请尝试将其移至过程下方。
    猜你喜欢
    • 2012-01-22
    • 2014-01-09
    • 2020-05-05
    • 2016-01-08
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    相关资源
    最近更新 更多