使用函数而不是过程来初始化派生类型

Using function instead of procedure to initialize derived type

如何使用函数从 Base 类型初始化派生类型?

如果我可以使用 function Create 而不是过程会更好看。

procedure Main is

   type Base is abstract tagged record
      Number : Integer;
   end record;

   type Base1 is new Base with null record;
   type Base2 is new Base with null record;

   --function Create return Base'Class is
   --begin
      --return (Number => 1);
   --end;

   procedure Create ( B : out Base'Class ) is
   begin
      B.Number := 1;
   end;

   B1 : Base1;
   B2 : Base2;

begin

   Create (B1);
   Create (B2);

end Main;

取消注释 function Create 时的生成器结果:

type of aggreate cannot be class-wide

我不想要那个错误。

只要函数知道哪个后代,就没有什么可以阻止函数返回抽象标记类型的具体后代的实例。你的 Create 没有。

一种方法是提供一个参数说明具体 class:

function Create (Kind : Integer) return Base'Class is
begin
   case Kind is
      when 1 =>
         return Base1'(Number => 1);
      when others =>
         return Base2'(Number => Kind);
   end case;
end Create;

另一种方法是声明一个返回 Base 的函数,它必须是 abstract,并覆盖派生类型。这必须在一个包中完成(我已经使用了 Ada2012 功能,如果它很简单,您可以在线编写一个函数的实现):

package Types is
   type Base is abstract tagged record
      Number : Integer;
   end record;
   function Create return Base is abstract;

   type Base1 is new Base with null record;
   function Create return Base1 is ((Number => 1));

   type Base2 is new Base with null record;
   function Create return Base2 is ((Number => 2));
end Types;

现在,因为在 Ada 中子程序可以分派函数结果和参数,你可以这样写

B4 : Types.Base1 := Types.Create;
B5 : Types.Base2 := Types.Create;

这个的问题在于您仅限于在基本函数中指定的参数配置文件。


以上所有假设您希望初始化取决于实际的具体类型。如果不是这样,您可以使用简单的初始化程序初始化为常量值:

type Base is abstract tagged record
   Number : Integer := 42;
end record;

或通过函数调用:

type Base is abstract tagged record
   Time : Ada.Calendar.Time := Ada.Calendar.Clock;
end record;