公平地说,我不能完全确定标题正确地描述了我所遇到的问题,因为它只是反映了我目前对Ada的理解。
我有一个功能:
function Make_Option (Title : String) return Access_Option is
O : aliased Option := (
Title_Len => Title'Length,
Title => Title);
begin -- Make_Option
return O'Unrestricted_Access;
end Make_Option;
此功能应该为用户创建一个新的菜单选项,然后可以将其插入菜单(您可能在基于终端的环境中看到的菜单)。您可能都在叹气,很明显,O
变量将在此函数结束时解除分配(根据我目前的理解)。因此,在这里使用Unrestricted_Access
只是简单的愚蠢,但它反映了我想要完成的结果(因为这段代码确实编译成功)。
Access_Option
定义如下:
type Access_Option is access all Option;
我们的想法是,通过访问选项(这又是一个有区别的记录),我们可以将它存储在类似数组的结构中(因为对象本身的大小不同)。
毫无疑问,如果我们可以改为使用Access
属性,那将是很好的,因为编译器将确保生命周期足够长我们引用的O
变量,但因为事实上生命周期只存在直到在Make_Option
函数结束时,我们将看到以下内容:
non-local pointer cannot point to local object
我当时要问的是:我将如何为我创建一个Access_Option
s函数?这样的事情是否可能,或者我做错了什么?为了澄清,我想要做的是创建一个简洁的方法来填充数组,引用有区别的记录,然后我可以取消引用和使用。
我个人没有尝试过太多的东西,而是考虑可能对问题有用的解决方案。而且,坦率地说,有一个解决方案适用于大规模应用程序,而不是将代码库搞得糟糕,而不是疯狂地使用临时解决方案。
你可能有某种对象队列来处理它吗? Ada是否甚至首先自动释放资源?嘎。我很迷惑。
事实上,它是否有可能以某种方式将O
变量置于释放范围之外,然后再手动解除分配?
给出上面显示的示例,一个更简单的方法是简单地创建一个Unbounded_String数组:
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO; use Ada.Text_Io;
procedure Str_Arrays is
type Arr is array(1..10) of Unbounded_String;
A : Arr;
begin
for S of A loop
S := To_Unbounded_String("Hello World!");
end loop;
for S of A loop
Put_Line(To_String(S));
end loop;
end Str_arrays;
不要试试。
有两种替代选择:
1)使用Ada.Containers.Indefinite_Vectors而不是普通数组。
2)给你的记录判别一个默认值。然后,您可以将其存储在普通数组中。
你似乎正在重新发明有界的字符串。替代方案包括
Ada.Strings.Bounded.Generic_Bounded_Length
的实例化Ada.Strings.Unbounded
Ada.Containers.Indefinite_*
)来保持类型String