在 Emba 的網站上,宣告一個 OUT 引數(沒有說是哪種型別,所以我假設它適用于所有型別)不應該用于輸入,因為它的值被“丟棄”。
通過丟棄,我解釋(即使我們不在圣經學習時間)該值已歸零。
但是,對于 out 引數,參考變數的初始值會被傳遞給它的例程丟棄。
但是這個簡單的代碼表明“i”沒有被丟棄(在任何情況下都沒有)!
Procedure TestInteger(OUT i: Integer);
Begin
if i = 7
then i:= 14;
End;
TYPE TMyRec = record
i: Integer;
end;
Procedure TestRec(OUT R: TMyRec);
Begin
End;
procedure TfrmTest.btnTestClick(Sender: TObject);
begin
VAR i: Integer:= 7;
TestInteger(i);
VAR MyRecord: TMyRec;
MyRecord.i:= 7;
TestRec(MyRecord);
Caption:= IntToStr(MyRecord.i);
end;
那么,檔案是錯誤的嗎?是我的“解釋”錯了,還是編譯器錯了?
uj5u.com熱心網友回復:
裝飾一個引數out意味著該引數將只用于回傳一個值給呼叫者;例程不得對引數的初始值做出任何假設。
out修飾作為對程式員的語意提示。此外,編譯器可能會利用“傳遞的”值將不會用于優化生成的代碼的知識。
但是,不能保證“通過”值確實被清除。畢竟,這樣的保證是沒有用的;相反,它可能會迫使編譯器生成效率稍低的代碼(因為清零記憶體需要時間)。
想一想手表制造商可以使手表在低至 ?50°C 的溫度下仍能正常作業。然后,您訂購的手表只需要能夠在低至 ?20°C 的溫度下正常運行。制造商可以利用這些知識以更便宜的價格生產手表。但是,絕對不能保證您收到的手表在 ?50°C 時會發生故障,您通常也不需要這樣的保證。(但當然不能在 ?20°C 以下使用手表。)
但是,對于 out 引數,參考變數的初始值會被傳遞給它的例程丟棄。
好吧,既然程式員從不使用這個值,它實際上就被“丟棄”了,不是嗎?
稍后在同一頁上:
在程式控制傳遞給程序之前,對 GetInfo 的呼叫會立即釋放 MyRecord 使用的記憶體。
好吧,這很難不被認為是錯誤的。
uj5u.com熱心網友回復:
請注意,如果您使用托管記錄,它會呼叫初始化并且 0 會在標題中結束。
TYPE TMyRec = record
i: Integer ;
class operator Initialize (out Dest: TMyRec);
end;
class operator TMyRec.Initialize (out Dest: TMyRec);
begin
dest.i := 0;
end;
這更像是評論,但代碼在評論中的格式不正確。
uj5u.com熱心網友回復:
我認為這樣做有兩個目的。一種是給程式員的,一種是給編譯器的。
Pascal 對所有方法引數使用“按值傳遞”語意,但 ObjectPascal 對物件使用“按參考傳遞”。您始終可以傳遞一個指標并根據需要對其進行轉換,但是很長一段時間以來,只有“const”和“var”。您將使用“const”來告訴編譯器該方法不會修改該值,從而允許它進行一些優化。
相反,usingvar告訴編譯器該方法確實修改了值,并且它通過參考(隱含指標)傳遞變數以啟用它。使用var還意味著它是雙向的,這意味著可能會傳入一個初始值,并且很可能在回傳時對其進行修改。這完全取決于你。如果不需要,代碼可以隨意忽略輸入值。
然后他們將inand添加out到語言中, wherein類似于const(AFAIK),但out不完全相同var- 它告訴編譯器假設該方法正在回傳該引數中的值,但它不關心發送的內容in. 就像var引數一樣,它需要通過參考傳遞,所以總會有一些東西可以被方法看到。但這更像是一份“合同”,你明確地說,“這是一扇外門,我們不希望任何人通過它進來。” 這并不意味著某人不能違反規則。這只是意味著如果您這樣做,則無法保證會發生什么。
現在你四處看看你告訴編譯器你不感興趣的東西里面有什么。你找到了一些東西,因為變數必須通過參考傳遞,所以它必須有一些值(因為沒有例如可為空的值)。
我唯一的問題是......你告訴編譯器該方法不關心輸入值可能是什么;那么你為什么要在這里發布一個問題,說明顯而易見的問題并詢問“為什么要傳遞一個值?”
我知道手冊中的措辭可能會說它是“丟棄的”,但合同上說它是無關緊要的,不會被審查。
我的意思是,您撰寫了代碼!如果你在告訴別人你不會那樣做后查看一個盒子,你期望發生什么?它應該戳你的眼睛嗎?爆炸?表現得像個插孔玩具?
如果您的方法需要雙向引數,請使用var. 如果它只需要多個 RETURN 引數,則out對每個引數使用。是的,您只能在為每個引數分配的記憶體空間中看到一個值,out因為它是通過參考傳遞的。但是請考慮一下,對于函式的單個 RETURN 值,沒有辦法訪問它,對吧?你為什么不抱怨你也看不到那個價值?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/536568.html
標籤:德尔福
上一篇:使用執行緒用TStringList中的專案填充TComboBox
下一篇:在Delphi中加密大字串
