9

完全作为 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);

显然,这不是几个月的自然顺序,我可以看到人们/我正在尝试做Month_Type'First或期望得到一月份的事情。

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

  1. 我可以有一个子类型来指定其基本类型的特定组件而不是范围吗?
  2. 我可以以某种方式隐藏我放置月份的顺序的实现细节(例如,让'First不可见)?

谢谢!

4

4 回答 4

6

不,枚举 子类型在这种情况下只允许range_constraint,但您可以使用Ada.Containers.Ordered_Sets. 这里这里都有例子。

于 2012-09-01T02:41:39.980 回答
6

您可以创建一个仅指定枚举中某些值的对象。我们通常称其为“集合”。

许多语言都将集合作为基本类型(以及数组和记录)。当然有些没有。艾达在中间。它通常没有名为“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;
于 2012-09-01T17:43:49.593 回答
4

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

subtype Short_Month_Type is Month_Type with
  Static_Predicate => Short_Month_Type in April | June | September | November
于 2018-01-15T22:54:27.710 回答
2

垃圾神回答了第一个问题。要回答第二个问题,请将类型本身设为私有。

于 2012-09-01T15:06:38.440 回答