Ada 通用包管理?
我刚刚开始使用Ada,我发现通用包声明相当愚蠢。也许我做得不对,所以我在寻找更好的选择 看看下面的例子Ada 通用包管理?,ada,Ada,我刚刚开始使用Ada,我发现通用包声明相当愚蠢。也许我做得不对,所以我在寻找更好的选择 看看下面的例子 package STD_Code_Maps is new Ada.Containers.Map(Key_Type => STD_Code_Type; Element_Type => Ada.Strings.Unbounded.Unbounded_String); STD_Code_Map : STD_Code_Maps.Ma
package STD_Code_Maps is new
Ada.Containers.Map(Key_Type => STD_Code_Type;
Element_Type => Ada.Strings.Unbounded.Unbounded_String);
STD_Code_Map : STD_Code_Maps.Map;
-- . . .
procedure Do_Something is
Item : Ada.Strings.Unbounded.Unbounded_String;
begin
Item := STD_Code_Maps.Element(STD_Code_Maps.First(STD_Code_Map));
-- Do something with the Item
-- . . .
end Do_Something;
如果能够简单地编写STD_-code_-Map.First.Element
,而不是被遗弃的STD_-code_-Map.Element(STD_-code_-Map.First(STD_-code_-Map)),那就更干净了代码>
显然我做错了,我想。我在那里至少重复了三次STD_代码_地图这个短语。我完全赞成冗长和一切,但实际上我写的代码对我来说是糟糕和愚蠢的
我想知道是否有解决方案不要求您将包重命名为包映射重命名STD\u code\u映射代码>这当然会缩短代码,但我不想在每个过程条目上都这样做。我真的认为像STD\u code\u Map.First.Element
这样的东西会简单得多。这能在2012年完成吗
注意:默认情况下使用无界_字符串包也很困难。标准库设计者是否真的对荒谬且过长的包层次结构给予了很多考虑
感谢您阅读本文,并有可能帮助我。我是Ada的新手。Ada是为可读性和可维护性而设计的。(写一次,读和维护更长时间)这意味着它有时会变得有点冗长。如果你喜欢简洁和神秘的语言,还有很多其他的语言
如果要避免一直键入STD_Code_Map,只需使用use
子句:
use STD_Code_Map;
这意味着你的行为准则
Item := STD_Code_Maps.Element(STD_Code_Maps.First(STD_Code_Map));
将成为
Item := Element(First(STD_Code_Map));
GNAT GPL 2012和2013以及FSF GCC 4.7和4.8支持Ada 2012的新容器索引方案,这意味着您可以编写
Item := STD_Code_Map ({some Cursor});
Item := STD_Code_Map (STD_Code_Map.First);
您甚至可以使用-gnat05
开关来强制Ada 2005模式!(这一定是个bug)
Ada 2005允许您使用object.function
表示法调用标记类型的基元函数,前提是第一个操作数为标记类型;因此,您可以编写STD\u-code\u-Map.First
作为STD\u-code\u-Map.First(STD\u-code\u-Map)
的缩写
把这些放在一起,你就可以写了
Item := STD_Code_Map ({some Cursor});
Item := STD_Code_Map (STD_Code_Map.First);
这很短 这个问题与泛型无关。正如Simon指出的,您可以说STD_Code_Map.First,因为STD_Code_Map的类型是标记类型,Ada支持标记类型的这种表示法。另一方面,STD_Code_Map.First的类型是一种游标类型,它没有标记(将其标记会导致声明同时使用游标和映射的某些操作时出现问题)。但是即使没有Simon提到的Ada 2012容器索引,您也可以说
STD_Code_Maps.Element(STD_Code_Map.First);
哪个好一点。除了重命名包外,还可以重命名函数:
function Elem (Position : STD_Code_Maps.Cursor) return STD_Code_Maps.Element_Type
renames STD_Code_Maps.Element;
现在,只要可以直接看到重命名,就可以使用Elem
而不是STD\u code\u Maps.Element
。(如果您愿意,可以将其称为元素
。重命名名称可以相同,也可以不同。)如果您经常使用该函数,这可能会很有帮助。在Ada中获得良好且可读的名称有时会很棘手。通常情况下,语言设计人员通过设计与Adause
子句一起使用的Ada标准库包,而没有考虑到他们会如何看待一些不能或不想使用该功能的可怜sap,从而使任务变得更糟
不过在这种情况下,有些事情你可以自己做
例如“_Maps.Map”是多余的,那么为什么不从包名中去掉它呢?为什么不使用名称,以便您可以编写:
package STD_Code is new
Ada.Containers.Map(Key_Type => STD_Code_Type;
Element_Type => Ada.Strings.Unbounded.Unbounded_String);
Map : STD_Code.Map;
-- . . .
procedure Do_Something is
Item : Ada.Strings.Unbounded.Unbounded_String;
begin
Item := STD_Code.Element(STD_Code.First(Map));
-- Do something with the Item
-- . . .
end Do_Something;
现在code
看起来也有点像一个没有意义的词。程序中的一切都是代码。所以我也会考虑抛弃它。毫无疑问,我将我的Ada容器包命名为表示其基本理论功能的东西(例如:STD_to_String
),而对象是更具体的名词
另外,我应该指出,如果您的映射是常量,并且您可以使用看起来像标识符的名称,那么通常情况下,您可以通过使用枚举类型和'image
属性完全消除字符串映射。如果您使用ADA2012,则使用STD_code_maps.Element(STD_code_maps.First(STD_code_map))代码>可能会变成:
Function Get_First( Map : STD_Code_Maps.Map ) return Unbounded_String is
( STD_Code_Maps.Element(Map.First) );
这是一个新表达式函数的示例,主要针对前置和后置条件引入
当然,如果您使用的是Ada 2012,那么您可能需要的精确映射是Ada.Containers.Indefinite\u Ordered\u Maps
——Indefinite\u*容器是那些[可以]具有不定元素的容器,如String
除了TED的评论之外,在映射为常量时使用枚举还有更多的优点,即案例覆盖率:编译器将把任何没有覆盖所有备选方案的案例语句标记为错误。因此,如果添加新代码,它将标记所有需要修改的case语句。(当然,当您使用其他人
案例时,此好处将丢失。)谢谢,但这是不可能的。在我的过程中,我有一个用于向量的use子句,因为这是我使用最多的东西。矢量。光标和贴图。光标冲突。在我明确第一个(…)返回Maps包的类型Cursor之前,代码不会编译。。。不是矢量包。我必须使用STD_Code_Maps.First()让编译器明白,然后我认为重命名是最好的选择<代码>包SCM重命名STD_代码_映射代码>应该会让生活更轻松。我想我现在就这么做吧。在学习Ada时,来自C/C++背景肯定是一个障碍。一个简单的方法就是向量a;项目=a[0]代码>我认为您可以理解编写item=vector.element(vector.first(a))代码>感觉太不对了。真是大错特错。唉。我