我需要制作一个泛型包,它的形参应该是访问子程序的类型。这种类型的对象被传递给这个包的子例程,我必须检查它是否为空相等。
generic
type Func_Type is private;
package Gen_Package is
function Check(Func : Func_Type) return Boolean is
(Func = null);
end;
但这不能编译,因为比较的左操作数没有访问类型。
答案 0 :(得分:5)
您可以利用访问类型对象的初始值为 []
的事实:
null
答案 1 :(得分:3)
您应该指定您需要的访问子程序类型作为形式参数。 Ada 语言参考手册第 12.5.4 节规定:“对于正式访问子程序子类型,指定的正式和实际配置文件应符合子类型。”
这导致声明如下:
generic
type func_type is access function(S : String) return string;
gen_func : not null func_type;
type proc_type is access procedure (Msg : in String);
gen_proc : not null proc_type;
package test_subprog is
procedure Print;
end test_subprog;
您必须声明对子程序类型的访问权限和对子程序实例的相应访问权限的形式参数。如果您指定形参必须为“非空”,那么您无需在代码中测试空参数。
with Ada.Text_IO; use Ada.Text_IO;
package body test_subprog is
-----------
-- Print --
-----------
procedure Print is
Msg : string := "This is a test";
begin
Put_Line(Item => gen_func(Msg));
gen_proc(gen_func(Msg));
end Print;
end test_subprog;
调用对作为泛型参数传递的子程序的正式访问不需要特殊的语法。制作一个使用泛型包的实际参数的实例可以这样做:
with Ada.text_io; use Ada.Text_IO;
with test_subprog;
procedure Main is
function format(S : String) return String is
begin
return "Called through function access " & S;
end format;
type format_access is access function(S : string) return String;
procedure reformat(S : String) is
begin
Put_Line("Called through procedure access " & S);
end reformat;
type proc_access is access procedure (S : String);
package sub_test is new test_subprog(func_type => format_access,
gen_func => format'access,
proc_type => proc_access,
gen_proc => reformat'access);
begin
sub_test.print;
end Main;
这种复杂的方法允许您使用对子程序类型的访问作为通用参数。除非您确实需要访问子程序类型,否则可以简单地使用子程序形式参数,如 Ada 语言参考手册第 12.6 节中所述:
通用形式子程序示例:
with function "+"(X, Y : Item) return Item is <>;
with function Image(X : Enum) return String is Enum'Image;
with procedure Update is Default_Update;
with procedure Pre_Action(X : in Item) is null; -- defaults to no action
with procedure Write(S : not null access Root_Stream_Type'Class;
Desc : Descriptor)
is abstract Descriptor'Write; -- see 13.13.2
-- Dispatching operation on Descriptor with default
-- given the generic procedure declaration
generic
with procedure Action (X : in Item);
procedure Iterate(Seq : in Item_Sequence);
-- and the procedure
procedure Put_Item(X : in Item);
-- the following instantiation is possible
procedure Put_List is new Iterate(Action => Put_Item);
答案 2 :(得分:2)
在通用数据包中也会传递一个接受这种类型的函数。
也许类似
generic -- GP
type Func_Ptr (<>) is limited private; -- Expected to be an access type
with function Is_Null (Ptr : in Func_Ptr) return Boolean;
with procedure Use_It (Ptr : in Func_Ptr);
package GP is
procedure Checked_Use (Ptr : in Func_Ptr);
end GP;
package body GP is
procedure Checked_Use (Ptr : in Func_Ptr) is
-- Nothing here
begin -- Checked_Use
if not Is_Null (Ptr) then
Use_It (Ptr => Ptr);
else
-- Handle null ptr
end if;
end Checked_Use;
end GP;
?
如果没有更多关于您的意图的信息,就很难提供帮助。通常,当您发现自己在与类型系统作斗争时,这表明您遇到了设计问题。