在我正在閱讀的一本教科書中聲明「雖然在編譯時檢查類型是否兼容,但子範圍需要運行時範圍檢查。」 如果我得到正確的結果,則必須在將新值分配給在特定子範圍(子類型)中定義的變量時執行運行時檢查。類型不一樣嗎?爲什麼這個區別?這只是編譯器的默認值?類型檢查和範圍檢查
回答
的確如此,從類型U
的子類型P
分配將不需要檢查,因爲不會有失配(即使子類型與該類型具有相同的範圍; subtype P is U;
是完全合法的,並且可以是有用!)
另一種方式,從類型到子類型,將涉及檢查,至少如果子類型是子範圍。
從外部看,另一種不同範圍的類型也是如此。但是,有一個微妙的差異,使用類型/子類型,您可以在不進行轉換的情況下將一個轉換爲另一個,如果不是沒有轉換,但是對於類型/類型,您必須在轉換之前進行類型轉換,並且將在轉換時檢查違反約束的條件,而不是轉讓。
這可能有助於說明這一點:
procedure Drimades is
type Upper is range 10 .. 20;
subtype Part is Upper range 10 .. 15;
type Lower is new Upper range 10 .. 15;
procedure Assign_U_To_P (U : Upper; To : out Part) is
begin
To := U; -- requires check
end Assign_U_To_P;
procedure Assign_P_To_U (P : Part; To : out Upper) is
begin
To := P; -- no check needed
end Assign_P_To_U;
procedure Assign_U_To_L (U : Upper; To : out Lower) is
begin
To := Lower (U); -- requires check
end Assign_U_To_L;
procedure Assign_L_To_U (L : Lower; To : out Upper) is
begin
To := Upper (L); -- no check required
end Assign_L_To_U;
U : Upper;
P : Part;
L : Lower;
begin
Assign_U_To_P (20, P);
Assign_P_To_U (15, U);
Assign_U_To_L (20, L);
Assign_L_To_U (15, U);
end Drimades;
與GNAT和-gnatG
產生這種中間表示,不要太用力,解釋我希望開關編譯如下:
procedure drimades is
type drimades__upper is range 10 .. 20;
[type drimades__TupperB is new short_short_integer]
freeze drimades__TupperB []
subtype drimades__part is drimades__upper range 10 .. 15;
[type drimades__TlowerB is new drimades__TupperB]
freeze drimades__TlowerB []
type drimades__lower is new drimades__upper range 10 .. 15;
procedure drimades__assign_u_to_p (u : drimades__upper; to : out
drimades__part) is
begin
[constraint_error when
not (u in 10 .. 15)
"range check failed"]
to := u;
return;
end drimades__assign_u_to_p;
procedure drimades__assign_p_to_u (p : drimades__part; to : out
drimades__upper) is
begin
to := p;
return;
end drimades__assign_p_to_u;
procedure drimades__assign_u_to_l (u : drimades__upper; to : out
drimades__lower) is
begin
[constraint_error when
not (u in 10 .. 15)
"range check failed"]
to := drimades__lower(u);
return;
end drimades__assign_u_to_l;
procedure drimades__assign_l_to_u (l : drimades__lower; to : out
drimades__upper) is
begin
to := drimades__upper(l);
return;
end drimades__assign_l_to_u;
u : drimades__upper;
p : drimades__part;
l : drimades__lower;
begin
drimades__assign_u_to_p (20, p);
drimades__assign_p_to_u (15, u);
drimades__assign_u_to_l (20, l);
drimades__assign_l_to_u (15, u);
return;
end drimades;
Simon Wright's answer地址從Ada及其亞型的角度提問,這意味着子集中的某個值,因此不是Ada或C++所稱的派生的類型或派生的類別,分別。 (型Lower
是新Upper
... ;
使得Lower
是衍生從Upper
,則所創建的子類型的「...」限定進一步的特徵。)
更一般地,一些語言允許任何變量名在運行時引用任何類型的對象。因此,在JavaScript中,
var a = 15, b = -1;
...
a = {"foo": "bar"}
...
return a + b;
將返回可能令人驚訝的結果,但如果通過語言判斷則結果很好。 a
在第二行上被賦予不同類型的新值,並且+
將在第三行上產生來自a
和b
的東西。
在Ada,C或Swift等語言中,並不需要這種靈活性:用這種語言編寫的程序可以在任何計算機設備上運行,這意味着不會像字典一樣在一個位置對象聲明是一些整數類型,說。編譯時間類型檢查可以防止這種情況。在分配(或傳遞)對象時需要在編譯時檢測到任何「不尊重」。
除編譯時類型檢查外,Ada還使用基於名稱的類型等價。所以,
type Apples is range 0 .. 20;
type Oranges is range 0 .. 20;
a : Apples := 5;
b : Oranges := 8;
return a + b; -- Error!
你得到
8. return a + b; -- Error!
|
>>> invalid operand types for operator "+"
>>> left operand has type "Apples" defined at line 2
>>> right operand has type "Oranges" defined at line 3
這是純粹的類型,在編譯時檢查。最後,擴展Simon Wright的例子說明的內容,有時Ada甚至要求在編譯時檢查子類型。然後涉及的短語是靜態匹配,其中靜態意味着編譯時。例如,相同的邊界。但是,這是先進的東西發生,例如,當指針指向堆棧上的對象,並且這些指針具有與指針不同的範圍(子類型)時。
- 1. SQL查詢檢查範圍
- 2. 會員檢查和日期範圍檢查在Matlab
- 3. 檢查範圍重疊
- 4. MySQL:BETWEEN ..如何檢查範圍?
- 5. ArrayList範圍檢查錯誤
- 6. PHP - 檢查日期範圍
- 7. 複製的範圍和重複檢查
- 8. 表格插入和範圍檢查?
- 9. 檢查類型
- 10. 類(類型)檢查
- 11. 使用枚舉進行類型檢查 - 如何正確範圍
- 12. XSLT類型檢查
- 13. typedef類型檢查?
- 14. 類型檢查Erlang
- 15. Prolog類型檢查
- 16. 檢查Genric類型
- 17. Typetree類型檢查
- 18. C#泛型和類型檢查
- 19. Django模型繼承和類型檢查
- 20. 檢查泛型類型是
- 21. 類型檢查的子類
- 22. Elif聲明檢查表單範圍
- 23. 檢查範圍是不是整個表?
- 24. 檢查ipAddress是否在私人範圍
- 25. 的Javascript檢查是否範圍重疊
- 26. c中的範圍檢查是什麼?
- 27. 如何檢查數組的範圍?
- 28. 添加範圍檢查的EditText
- 29. 檢查信息的範圍 - 雙擊
- 30. 範圍檢查錯誤畫布
你在說什麼語言? –
它適用於Ada,也可能適用於其他語言。 –
當你說「subrange check」時,你的意思是檢查在收集元素(如數組)時特定索引是否在允許範圍內?或者它有什麼不同? – oldbam