2016-09-28 136 views
2

我有一个字符串lx : String,我要为以后的价值在我的代码,但我发现了错误unconstrained subtype not allowed (need initialization) provide initial value or explicit array bounds为什么字符串需要用初始值初始化?

我也有一个字符串数组L_array : array (1 .. user_size) of String;,这是抛出错误unconstrained element type in array declaration。由于从文本文件中读取值,因此我无法初始化它。如果我想稍后设置这些值,我应该怎么做?

回答

8

确实存在两个问题,但具有相同的基本原因:String必须在创建时确定其大小(即约束)。

如果你知道它的大小,并且(在array of String的情况下)所有String都是相同的大小,限制它们很容易,不需要进一步评论。

想想未知长度的String意味着:未知的存储需求。一种方法是使用指针或访问类型,分配存储来保存字符串,并记住稍后释放它。这种方式与其他语言一样,有可能出现错误,内存泄漏等。猜测大小上限的替代方法也是如此,这可能会导致缓冲区溢出。你可以在Ada中做,就像其他语言一样,但是...不是最佳实践。

Ada提供了对这两种模式的抽象,分别为Unbounded_StringBounded_String,旨在最大限度地减少问题。但是它们的使用仍然不如String

有一个在comp.lang.ada新闻组这些抽象的(我使用谷歌组网关它道歉)

somewhat intense discussion所以我会建议方法可以做到这两个任务只是String


对于单串lx : String,你设置的值后开的情况下,答案很简单:只要声明String以后,用该值初始化。代替

lx : String; 

... 
lx := Read(My_File); 
Process_String(lx); 

使用declare代码段(通常在循环体):

...  
declare 
    lx : String := Read(My_File); 
begin 
    Process_String(lx); 
end; 

end字符串lx超出范围,并且它被重新创建(具有正确的尺寸,从的初始化,下一次到达declare块。


一种Array of String是比较困难的,如果每个部件具有不同的尺寸,和Bounded_StringUnbounded_String是有用的候选人。

但是另一种方法(因为Ada-2005)将使用Ada.Containers包而不是Array。这些都有明确和不确定的味道,你需要一个不确定的容器来存储不同大小的成员。具体来说Ada.Containers.Indefinite_Vectors作为矢量可以索引类似于一个数组。

这种方法与在C++中使用std_vector有相似之处,实际上标准模板库最初是用于Ada,后来被改编为C++。

在Ada-2005之前,Ada.Containers不是该语言的一部分,但是您需要使用来自外部库(如我认为)的Booch组件(Grady Booch)的等价物。

起动机:

with Ada.Containers.Indefinite_Vectors; 
with Ada.Text_IO; 

procedure String_Vector is 

User_Size : constant natural := 10; 
subtype Index is natural range 1 .. User_Size; 

-- Indefinite_Vectors is a generic package. 
-- You can't use it directly, instantiate it with index and content types 
package String_Holder is new Ada.Containers.Indefinite_Vectors(Index,String); 
-- make String_Holder operations visible 
use String_Holder; 

LV  : String_Holder.Vector;  -- initially empty 
L_Vector : String_Holder.Vector :=  -- initialise to size with empty elements 
      To_Vector(Ada.Containers.Count_Type(User_Size)); 


begin 
    L_Vector.Replace_Element(1,"hello"); 
    LV.Append("world"); 
    Ada.Text_IO.Put_Line(L_Vector(1) & " " & LV(1)); 
end String_Vector;