2009-02-09 39 views
6

當使用德爾福:如果我有一個充滿像常數單位...添加一個單元的接口使用條款,而不是實現使用條款

Unit AConsts; 
Interface 
Const 
    Const1 : WideString = 'Const1'; 
    Const2 : WideString = 'Const2'; 
    Const3 : WideString = 'Const3'; 
    Const4 = 100; 
    Const5 = 100; 
Implementation 
end. 

,我想從使用本機另一個單位,有

Unit AUnit; 
Interface 
Uses 
    AConsts; 
Implementation 
end. 

Unit AUnit; 
Interface 
Implementation 
Uses 
    AConsts; 
end. 

之間......有什麼區別? 換句話說,就編譯好的應用程序而言,兩者是否有區別?

[編輯1]

感謝您的回答。

我沒有把這個問題弄清楚,爲此我表示歉意。問題不在於範圍,避免循環引用等。它是關於編譯的應用程序的差異。也許另一個例子會有幫助。

如果UnitA,UnitB和UnitC都使用AConsts,那麼App1在這些UnitA,UnitB和UnitC都有的編譯應用程序中會有差異(假設AConsts單元和其他代碼中的常量之間沒有名稱衝突)在接口部分的使用條款和App2中,UnitA,UnitB和UnitC都在實現部分的使用條款中包含AConsts。

+0

也許我有點老派,但我認爲在界面中你應該只使用你的聲明所需的單位,這些單位將在單元外部提供,因此在界面中。你應該把其餘的部分放在實施中。 AFAIK,在古代,這有助於編譯速度和結果EXE大小,最近的版本處理的更好。但是,它仍然是一個整潔的方式。 – 2015-07-06 08:56:43

回答

10

不同之處在於你可以參考AConsts在其界面部分中的內容。在第一個AUnit中,可以使用Const4來聲明中的固定大小數組接口部分。您無法在第二個AUnit中這樣做,因爲Const4不在範圍內。

可以對編譯後的程序有影響,如果你不小心的話。假設我們有另一個單元聲明一個名爲Const4常數:

unit BConsts; 
interface 
const 
    Const4 = 50; 
implementation 
end. 

現在我們在UnitA定義數組是這樣的:

unit AUnit 
interface 
uses BConsts; 
var 
    data: array[0..Pred(Const4)] of Integer; 
implementation 
uses AConsts; 
procedure Work; 
var 
    i: Integer; 
begin 
    for i := 0 to Const4 - 1 do begin 
    data[i] := 8; 
    end; 
end; 
end. 

該代碼會寫超越的結束數組,因爲在接口部分範圍內的Const4與實現部分中使用的Const4不同。這不會經常發生在常量上。它通常發生在兩個標識符中,即在WindowsSysUtils中定義的FindClose函數和在GraphicsWindows中定義的TBitmap。在這兩種情況下,編譯器會告訴你,你做錯了什麼,儘管它不會精確地告訴你,你已經使用了一個具有兩種不同含義的標識符。您可以通過限定標識符解決問題:

for i := 0 to BConsts.Const4 - 1 do 
    data[i] := 8; 

如果所有上述措施得到解決,所以你的程序編譯和運行正常的話,那沒有什麼區別,其中單位使用。在你的App1和App2的例子中,這兩個程序將是相同的。它們不會完全相同 - 編譯器會以不同的順序處理事件,因此可能會將事物放在不同的地方 - 但它不會影響程序的執行。

1

界面中uses語句中的項目在整個單元中都是可見的。

實現中uses語句中的項僅在實現部分中可見。

例子:

unit A; 
interface 
const 
    cA = 1; 
.. 


unit B; 
interface 
const 
    cB = 1; 
.. 



unit C; 
interface 
uses 
    A; 
const 
    cC1 = cA; 
    cC2 = cB; // Error 

implementation 
uses 
    B; 
const 
    cC3 = cA; 
    cC4 = cB; 

end. 

如果至少一個單元包括在執行部分,您可以創建互相關單位:如果同時在接口部分採用

unit A; 
interface 
implementation 
uses 
    B; 
end. 


unit B; 
interface 
implementation 
uses 
    A; 
end. 

也不會編譯/鏈接。

2

IDE還使用如何聲明您的用途以確定需要編譯的內容。

如果你的接口部分使用UnitA,並且你的實現部分使用UnitB,那麼如果單元B需要重新編譯,你的單元不會,但是如果unitA發生改變,那麼你的單元需要重新編譯。

這是Delphis超快建立速度的祕訣之一。

至於你完成的可執行文件,我希望無論你在哪裏放置聲明(連接器都很聰明,只有你的應用程序實際使用的方法等鏈接),它的大小將變成相同大小,但實際位置如果單位聲明的順序發生變化,各種來源幾乎肯定會改變。

1

我遵循一個規則,我把所有的東西放在接口部分,除非我需要處理循環引用的問題。這有助於帶來一點清晰。 Delphi中的一些嚮導和「File> Use Unit ...」對話框將單元放在實現部分。

除Rob Robinson着重介紹的範圍陷阱外,沒關係。制定你的標準並堅持下去。

3

我把所有的引用放在實現部分中,只把這些單元名稱放在我必須的接口中。

雖然我喜歡儘可能地限制所有事情的範圍,而且這個政策是依據的。