Ada 程式設計/屬性/'Base
表示另一個型別或子型別的基型別。此屬性用於訪問基型別的屬性。
T'Base 指的是型別的“基範圍”,它定義了中間計算執行的範圍。
標準規定 T'Base 的範圍
- 包括值 0
- 關於零對稱,可能有一個額外的負值
- 包括子型別 T 中的所有值
例如,如果 T 是
typeTisrange1 .. 42;
那麼編譯器將選擇一個包含此範圍的硬體支援型別,在本例中可能是八位型別(在二進位制補碼機器上)
typeT'Baseisrange-128 .. 127;
此定義不應被理解為字面意思,因為根據 Ada 語義,T 和 T'Base 不相容。實際上,T 的宣告將是
subtypeTisT'Baserange1 .. 42;
請注意,內建運算子透過基型別執行,例如 T 的“+”運算子被隱式宣告為
function"+" (L, R : T'Base)returnT'Base;
T'Base 上沒有約束檢查,例如
declareO1 : T := T'(1) + T'(2); O2 : T'Base := T'(1) + T'(2);begin
那麼在對 O1 的第一次賦值中,有一個約束檢查以確保 1 + 2 的結果在 T 的範圍內,但在對 O2 的第二次賦值中,沒有檢查。
T'Base 對泛型很有用,當你需要能夠恢復型別的基範圍時,以便宣告一個值為 0 的物件;例如,如果這是一個累加器。
瞭解型別的基範圍是有幫助的,這樣你就能保證在中間計算中不會發生溢位。例如,給定上面的型別 T,那麼
procedureOp (O1, O2 : T)isSum : T'Base := O1 + O2;begin
這是一個問題,因為如果 O1 和 O2 的總和很大(即大於 T'Base'Last),那麼就會發生溢位。知道要將兩個值加在一起意味著你應該以這種方式宣告型別
T_Last :constant:= 42;typeT_Baseis0 .. 2 * T_Last;subtypeTisT_Baserange1 .. T_Last;
這樣你就知道(子)型別 T 的範圍是 1 .. 42,但你也保證 T'Base'Last >= 84,因此兩個型別 T 的值的總和不會溢位。
請注意,以下形式的宣告
typeTisrange...
實際上聲明瞭一個名為 T 的子型別,它屬於某個匿名基型別。我們可以將此基型別的範圍稱為 T'Base。
列舉型別是它自己的基型別,因此給定此型別
typeETis(A, B, C);
那麼 ET 的範圍與 ET'Base 的範圍相同。如果你在你的“基”型別中需要一些額外的文字,那麼你必須手動宣告它們,這與我們上面所做的類似
typeET_Baseis(ET_Base_First, A, B, C, ET_Base_Last);subtypeETisET_BaserangeA .. C;
現在你可以說 ET'Succ (ET'Last),你將得到一個有意義的答案。這在執行以下操作時是必需的
declareE : ET'Base := ET'First;beginwhileE <= ET'Lastloop... -- do something E := ET'Succ (E);endloop;end;
同樣,當你從 ET_Base 派生並使用範圍約束時,派生型別的基型別將包含基型別的所有值
typeNew_ETisnewET_BaserangeA .. C; Correct:constantBoolean := New_ET'Base'First = ET_Base_First;
請注意,這裡 ET_BASE_First 的型別為 New_ET。
如果你宣告
typeMy_Enumis(Enum1, Enum2, Enum3);
並且
subtypeSub_EnumisMy_EnumrangeEnum1 .. Enum2;
那麼Sub_Enum'Base'Last是Enum3.
