Ada/Gnat -- 包级动态泛型实例化

Ada/Gnat -- Package-level dynamic generic instantiation

我有一个通用包:

generic
    Size : Positive;
package Foo is

    type Unbounded_Sized_Array is Array(1..Size) of Unbounded_String;

    type My_Type is
    record
        My_Array : Unbounded_Sized_Array;
        --other stuff
    end record;

end Foo;

我需要在另一个包的包级别声明它:

package Bar is

    package Dynamic_Foo is new Foo(Count);

    --other stuff

end Bar;

问题是在我执行一些代码之后我才知道 Count 是什么(它是给定目录中的文件数)并且我不确定如何推迟 [=20= 的实例化] 直到完成之后。或者即使那是可以在 Ada 中完成的事情。我可以创建一个链表类型,但我真的不想这样做,因为 size/length 在启动后应该保持不变。

您可以在任何声明区域中声明新类型和实例化泛型,因此您可以简单地将实例化移动到 Count 具有正确值的点。

您也可以使 Count 成为一个函数,returns 就是您需要的值。然后 Count 将在您实例化函数的地方调用,一切都会很好(除了我在评论中提到的竞争条件)。

例如:

with Ada.Text_IO; use Ada.Text_IO;
with Foo;

procedure Proc1 is
   Count : Positive := 5;
   package Foocounted1 is new Foo (Count);
   A : Foocounted1.Unbounded_Sized_Array;
begin
   Put_Line ("A'Length = " & Integer'Image (A'Length));
   Count := Count + 20;
   declare
      package Foocounted2 is new Foo (Count);
      B : Foocounted2.Unbounded_Sized_Array;
   begin
      Put_Line ("B'Length = " & Integer'Image (B'Length));
   end;
end Proc1;

在我看来你想要一个 Unbounded_String 的无限数组。在 Ada 中,无界数组由名为的包提供,正如您对无界数组的 pkg 所期望的那样,Ada.Containers.Vectors:

package File_Lists is new Ada.Containers.Vectors (Index_Type => Positive, Element_Type => Unbounded_String);

File : File_Lists.Vector;

Get_Files : loop
   exit Get_Files when No_More_Files;

   File.Append (New_Item => Next_File);
end loop Get_Files;

这样就不用先统计文件个数了