Ada中亚型的非连续范围?

J C*_*per 8 types visibility ada

完全作为Ada类型系统学习练习,我试图制作3种类型(或者更确切地说,类型和2种子类型):

  • Month_Type,所有月份的列举
  • Short_Month_Type,一个Month_Type只有30天的月份的子类型
  • February_Month_Type,一个只有二月的子类型

似乎子类型必须使用range机制,对吗?(还有其他类型的子类型吗?)为了让它与连续的范围一起工作,我必须Month_Type按以下顺序放置我的枚举:

   type Month_Type is (February, April, June, September, November, January, March, May, July, August, October, December);
Run Code Online (Sandbox Code Playgroud)

显然这不是几个月的自然顺序,我可以看到人们/我想要做什么Month_Type'First或者想要获得一月的东西.

所以,这个愚蠢的例子中有两个一般问题:

  1. 我可以使用指定其基本类型的特定组件而不是范围的子类型吗?
  2. 我可以以某种方式隐藏我放入月份的订单的实现细节(例如,"首先不可见")?

谢谢!

tra*_*god 6

不,一个枚举 亚型只承认一个range_constraint在这种情况下,但你可以创建任意数量的设置使用Ada.Containers.Ordered_Sets.这里这里都有例子.


cas*_*avo 6

您可以使用子类型谓词。在你的情况下:

subtype Short_Month_Type is Month_Type with
  Static_Predicate => Short_Month_Type in April | June | September | November
Run Code Online (Sandbox Code Playgroud)


T.E*_*.D. 5

您可以创建一个仅指定枚举中某些值的对象.我们通常称之为"集合".

许多语言都设置为基本类型(以及数组和记录).当然有些人没有.阿达有点中间.它没有正式的类型名为"set"或任何东西,但布尔运算被定义为像数组上的按位逻辑运算一样工作boolean.如果你打包数组,你几乎可以得到其他语言的"set"类型给你的东西.所以Ada支持集合,它们只是被称为"布尔数组".

type Month_Set is array (Month) of Boolean;
Short_Month : constant Month_Set := 
    (September => true, April => true, June => true, November => true, 
     February => true, others => false);
Y_Month : constant Month_Set :=
    (January => true, February => true, May => True, July => true, 
     others => false);

-- Inclusion
if (Short_Month(X)) then ...

-- Intersection (Short_Y will include only February)
Short_Y := Short_Month and Month_Ending_in_Y;

-- Union (Short_Y will include All Short_Months and all Y_Months
Short_Y := Short_Month or Month_Ending_in_Y;

-- Negation (Short_Y will include all Short_Months not ending in Y
Shorty_Y := Short_Month and not Month_Ending_in_Y;
Run Code Online (Sandbox Code Playgroud)