我在程序包中有一些方法可以对带有标记记录的访问常量进行操作;为了调用这些函数,我必须指定程序包名称。我宁愿只输入变量名[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;
答案 0 :(得分:5)
这不起作用,因为根据您的定义,foo
不是标记类型为Color
的原始操作。前缀表示法只能用于标记类型的原始操作。
解决方案是使foo
成为Color
的原始操作,如下所示:
procedure foo (C : access constant Color) is
begin
null;
end foo;
如果您使用命名访问类型,则foo
将是该类型的原始操作,并且由于该类型不是标记类型,因此前缀表示法不起作用。
答案 1 :(得分:5)
问题在于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;
我宣布Foo
服用in Color
;您也可以根据需要将其声明为采用access constant Color
,因为(ARM 4.1.3(9.2))
子程序的第一个形式参数应为T类型,或覆盖T的全类类型,或指定这些类型之一的访问参数。