跳轉到內容

Ada 程式設計/型別/列舉

來自華夏公益教科書,開放的書籍,為了一個開放的世界

Ada. Time-tested, safe and secure.
Ada。經久耐用,安全可靠。

列舉型別定義為可能的取值的列表

 type Primary_Color is (Red, Green, Blue);

就像數值型別一樣,例如 1 是一個整數字面量,Red、Green 和 Blue 被稱為此型別的字面量。 此型別沒有其他可分配的值。

運算子和屬性

[編輯 | 編輯原始碼]

除了相等性 ("=") 之外,列舉型別上唯一的運算子是排序運算子: "<"、"<="、"="、"/="、">="、">",其中排序關係由字面量的順序隱式給出:每個字面量都有一個位置,從第一個開始為 0,每個後續字面量遞增 1。此位置可以透過 'Pos 屬性 查詢;逆運算為 'Val,它返回相應的字面量。在我們的示例中

Primary_Color'Pos (Red) = 0
Primary_Color'Val (0)   = Red

還有兩個重要的屬性:'Image'Value(不要將 'Val'Value 混淆)。'Image 返回值的字串表示形式(大寫字母),'Value 是反向操作

Primary_Color'Image ( Red ) = "RED"
Primary_Color'Value ("Red") =  Red

這些屬性對於簡單的IO 很重要(在 Ada.Text_IO 中有更復雜的 IO 功能,用於列舉型別)。請注意,由於 Ada 不區分大小寫,因此傳遞給 'Value 的字串可以是任何大小寫。

列舉字面量

[編輯 | 編輯原始碼]

字面量是可以過載的,也就是說你可以用相同的字面量擁有另一個型別。

type Traffic_Light is (Red, Yellow, Green);

在使用字面量的上下文中,過載解析通常會解析出哪個 Red 是指的。 只有當存在無法解析的過載衝突時,才能使用特殊語法來限定哪個 Red 是指的

Primary_Color'(Red)

與許多其他宣告性專案一樣,列舉字面量可以被重新命名。 事實上,這樣的字面量實際上是一個函式,因此它必須被重新命名為函式

function Red return P.Primary_Color renames P.Red;

在此,Primary_Color 被假定在包 P 中定義,該包在重新命名宣告的位置可見。 重新命名使 Red 直接可見,無需使用 use 子句。

請注意,作為函式的重新宣告不會影響字面量的靜態性。

字元作為列舉字面量

[編輯 | 編輯原始碼]

Ada 中非常獨特的是將字元字面量用作列舉字面量

 type ABC is ('A', 'B', 'C');

這個字面量 'A' 與預定義型別 Character(或 Wide_Character)的字面量 'A' 完全沒有共同之處。

每個至少有一個字元字面量的型別都是字元型別。 對於每種字元型別,字串字面量和連線運算子 "&" 也隱式定義。

type My_Character is (No_Character, 'a', Literal, 'z');
type My_String is array (Positive range <>) of My_Character;

S: My_String := "aa" & Literal & "za" & 'z';
T: My_String := ('a', 'a', Literal, 'z', 'a', 'z');

在此示例中,S 和 T 的值相同。

Ada 的 Character 型別就是這樣定義的。 參見Ada 程式設計/庫/Standard.

布林值作為列舉字面量

[編輯 | 編輯原始碼]

布林值也定義為列舉型別

 type Boolean is (False, True);

此宣告中隱含著特殊語義,即此型別的物件和表示式可以用作條件。 請注意,字面量 False 和 True 不是 Ada 關鍵字。

因此,僅僅宣告一個具有這些字面量的型別,然後希望此型別的物件可以用作這樣,是不夠的

 type My_Boolean is (False, True);
 Condition: My_Boolean;

 if Condition then -- wrong, won't compile

如果需要自己的布林值(可能具有特殊的尺寸要求),則需要從預定義的布林值派生

 type My_Boolean is new Boolean;
 Condition: My_Boolean;

 if Condition then -- OK

列舉子型別

[編輯 | 編輯原始碼]

您可以使用範圍為列舉型別建立子型別

 subtype Capital_Letter is Character range 'A' .. 'Z';
 type Day_Of_Week is (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
 
 subtype Working_Day is Day_Of_Week range Monday .. Friday;

使用列舉

[編輯 | 編輯原始碼]

列舉型別是標量子型別,因此型別屬性如FirstSucc將允許遍歷值的子序列。

     case Day_Of_Week'First is
        when Sunday =>
           ISO (False);
        when Day_Of_Week'Succ (Sunday) =>
           ISO (True);
        when Tuesday .. Saturday =>
           raise Program_Error;
     end case;

迴圈將自動遍歷子類型範圍內的值。 過濾工作日以僅包含偶數位置的工作日

     for Day in Working_Day loop
        if Day_Of_Week'Pos (Day) mod 2 = 0 then
           Work_In_Backyard;
        end if;
     end loop;

列舉型別可用作陣列索引子型別,從而產生表格功能

  type Officer_ID is range 0 .. 50;
  type Schedule is array (Working_Day) of Officer_ID;

華夏公益教科書

[編輯 | 編輯原始碼]

Ada 參考手冊

[編輯 | 編輯原始碼]
華夏公益教科書