字符串文字的 Ada 常量数组
Ada constant array of string literals
我有一个很大的 C 数组,我想将其移入我的 ada 项目中。该数组用于存储稍后将加载的资产的文件名。它看起来像:
const char *filenames[NUMBER_OF_FILES] = {
/* file[0] */ "res/0.file",
/* ... */
/* file[n] */ "res/some_more/complicated/file.name"
};
我想把它移到 ada 包体中,但找不到合适的方法。显然我的第一次尝试是:
filenames : constant array (File_Index) of String := (
index_0 => "res/0.file",
-- ...
index_n => "res/some_more/complicated/file.name"
);
当然,String 是一种不受约束的类型,因此 Ada 不允许这样做。我将其切换为使用 Unbounded_Strings,这有效,但非常难看(必须用 To_Unbounded_String
包裹每个字符串。
有没有办法像这样创建一个大小在编译时已知的无约束类型数组,还是我必须使用无界字符串?
它有点低级和重复,但也许你可以创建一个小程序(甚至可以在 Ada 中!)来生成类似
的东西
with Ada.Text_IO; use Ada.Text_IO;
procedure Lambdabeta is
F1 : aliased constant String := "res/0.file";
F2 : aliased constant String := "res/some_more/complicated/file.name";
type Strings is array (Positive range <>) of access constant String;
Filenames : constant Strings := (F1'Access,
F2'Access);
begin
for J in Filenames'Range loop
Put_Line (Filenames (J).all);
end loop;
end Lambdabeta;
另请参阅 this answer 以最大程度地减少使用 To_Unbounded_String
的痛苦。
数组不能包含不确定类型的对象。
基本上你有两个选择:
- 使用另一个容器而不是数组。
- 将字符串封装成确定的类型。
所以你可以使用 Ada.Containers.Indefinite_Vectors
而不是数组:
with Ada.Containers.Indefinite_Vectors;
package Settings is
------------------------------------------------------------------
-- You may want to put this block in a separate package:
package String_Vectors is
new Ada.Containers.Indefinite_Vectors (Index_Type => Positive,
Element_Type => String);
function "+" (Left, Right : String) return String_Vectors.Vector
renames String_Vectors."&";
function "+" (Left : String_Vectors.Vector;
Right : String) return String_Vectors.Vector
renames String_Vectors."&";
------------------------------------------------------------------
File_Names : constant String_Vectors.Vector :=
"/some/file/name" +
"/var/spool/mail/mine" +
"/etc/passwd";
end Settings;
所以你可以使用 Ada.Strings.Unbounded.Unbounded_String
而不是 String
:
with Ada.Strings.Unbounded;
package Settings_V2 is
function "+" (Item : in String) return Ada.Strings.Unbounded.Unbounded_String
renames Ada.Strings.Unbounded.To_Unbounded_String;
type String_Array is array (Positive range <>)
of Ada.Strings.Unbounded.Unbounded_String;
File_Names : constant String_Array :=
(+"/some/file/name",
+"/var/spool/mail/mine",
+"/etc/passwd");
end Settings_V2;
还没有提到的是你可以只用一个函数:
subtype File_Index is Integer range 1 .. 3;
function Filename (Index : File_Index) return String is
begin
case Index is
when 1 => return "res/0.file";
when 2 => return "res/1.file";
when 3 => return "res/some_more/complicated/file.name";
end case;
end Filename;
在您的代码中使用 Filename (1)
与访问数组元素相同。
我有一个很大的 C 数组,我想将其移入我的 ada 项目中。该数组用于存储稍后将加载的资产的文件名。它看起来像:
const char *filenames[NUMBER_OF_FILES] = {
/* file[0] */ "res/0.file",
/* ... */
/* file[n] */ "res/some_more/complicated/file.name"
};
我想把它移到 ada 包体中,但找不到合适的方法。显然我的第一次尝试是:
filenames : constant array (File_Index) of String := (
index_0 => "res/0.file",
-- ...
index_n => "res/some_more/complicated/file.name"
);
当然,String 是一种不受约束的类型,因此 Ada 不允许这样做。我将其切换为使用 Unbounded_Strings,这有效,但非常难看(必须用 To_Unbounded_String
包裹每个字符串。
有没有办法像这样创建一个大小在编译时已知的无约束类型数组,还是我必须使用无界字符串?
它有点低级和重复,但也许你可以创建一个小程序(甚至可以在 Ada 中!)来生成类似
的东西with Ada.Text_IO; use Ada.Text_IO;
procedure Lambdabeta is
F1 : aliased constant String := "res/0.file";
F2 : aliased constant String := "res/some_more/complicated/file.name";
type Strings is array (Positive range <>) of access constant String;
Filenames : constant Strings := (F1'Access,
F2'Access);
begin
for J in Filenames'Range loop
Put_Line (Filenames (J).all);
end loop;
end Lambdabeta;
另请参阅 this answer 以最大程度地减少使用 To_Unbounded_String
的痛苦。
数组不能包含不确定类型的对象。
基本上你有两个选择:
- 使用另一个容器而不是数组。
- 将字符串封装成确定的类型。
所以你可以使用 Ada.Containers.Indefinite_Vectors
而不是数组:
with Ada.Containers.Indefinite_Vectors;
package Settings is
------------------------------------------------------------------
-- You may want to put this block in a separate package:
package String_Vectors is
new Ada.Containers.Indefinite_Vectors (Index_Type => Positive,
Element_Type => String);
function "+" (Left, Right : String) return String_Vectors.Vector
renames String_Vectors."&";
function "+" (Left : String_Vectors.Vector;
Right : String) return String_Vectors.Vector
renames String_Vectors."&";
------------------------------------------------------------------
File_Names : constant String_Vectors.Vector :=
"/some/file/name" +
"/var/spool/mail/mine" +
"/etc/passwd";
end Settings;
所以你可以使用 Ada.Strings.Unbounded.Unbounded_String
而不是 String
:
with Ada.Strings.Unbounded;
package Settings_V2 is
function "+" (Item : in String) return Ada.Strings.Unbounded.Unbounded_String
renames Ada.Strings.Unbounded.To_Unbounded_String;
type String_Array is array (Positive range <>)
of Ada.Strings.Unbounded.Unbounded_String;
File_Names : constant String_Array :=
(+"/some/file/name",
+"/var/spool/mail/mine",
+"/etc/passwd");
end Settings_V2;
还没有提到的是你可以只用一个函数:
subtype File_Index is Integer range 1 .. 3;
function Filename (Index : File_Index) return String is
begin
case Index is
when 1 => return "res/0.file";
when 2 => return "res/1.file";
when 3 => return "res/some_more/complicated/file.name";
end case;
end Filename;
在您的代码中使用 Filename (1)
与访问数组元素相同。