2013-04-15 69 views
-2

不幸的是,確切Assign簽名是不是在RTL源可用,我試圖去猜測,比如:什麼是System.Assign的確切簽名(用於程序表達式)?

const 
    Assign: procedure (var F; const FileName: string) = System.Assign; 
    { or } 
    Assign: function (var F; const FileName: string): Integer = System.Assign; 
    { also I tried "internal" one from _AssignFile } 

沒有取得任何積極的結果,和編譯器拒絕把這個含量的不同表達程序和抱怨約右值E2029 '(' expected but ';' found))。

那麼,我應該使用哪種類型來完全匹配Delphi RTL?

+2

有關簽名,請參閱文檔:http://docwiki.embarcadero.com/Libraries/XE2/en/System.Assign – ain

+2

@ain重載?內在? Emba的wiki在比這更簡單的情況下被損壞。 Jsut通過您的鏈接閱讀這三個(!)聲明... –

回答

4

Assign是Delphi的語言殘餘,它的起源是原始的Turbo Pascal語法。早在RTL的文本文件和「文件類型」內部數據結構被記錄之前,很久之前就已經在語言語法中添加了函數重載,但有Assign

Assign是一個足夠簡單的過程來使用,但是當你看它所要做的事情時,你會發現如果沒有某種編譯器的魔法實現是幾乎不可能的。 File of TFoo將創建一個與File of Integer不同且不兼容的文件類型。然而,兩者都可以作爲第一個參數傳遞給Assign

今天,您可能可以使用文件參數的泛型類型參數實現Assign。泛型類型將符合傳入的變量的類型。這非常棒,但是我們需要一種方法將類型化文件變量與字符串文件名關聯25年,然後纔將泛型添加到混合中。

Assign是一個編譯器的內在函數。這意味着它生活在Delphi/Pascal語法空間之外。 Assign實質上是一個類型一致性過程,它不能用強類型的Delphi/Pascal語言表示(沒有現代和複雜的語言擴展,如泛型)。它不是無類型的,它不是動態類型的,因爲實際的參數類型在編譯時完全確定。

你不能把Assign函數的地址。即使可以,因爲它是無定形的,您將無法定義準確表示其所有可能呼叫簽名的過程類型。

編譯器魔術函數存在於語言之外,用於處理在當時可用的語法中無法輕鬆表示的任務。 Assign就是一個例子。 Writeln()是另一個。

+0

但_AssignFile和_AssignText是不是內,這些都是在系統單元的全球慣例,但你仍然不能使用它們分配給程序變量,至少在XE2控制檯應用程序。爲什麼? –

+0

我似乎記得在以下劃線開始系統單元暴露所有的符號都沒有到單元外部Delphi代碼訪問。我可能是錯上,但不是這樣的:編譯器固有的符號映射到基於在使用固有的語境系統單元實現。另外,歷史上,系統單元中的許多內部實現都沒有正式的參數列表。它們通過語法外的編譯器定義的寄存器接收參數。 – dthorpe

0

如果打開System.pas文件並讀取它,在XE2你有這些內部程序:

function _AssignFile(var t: TFileRec; const s: PChar): Integer; 
function _AssignText(var t: TTextRec; const s: PChar; const CP: word): Integer; 

而且我不認爲你有任何全球穩定程序W/O名稱中下劃線 - 那些列出的是Delphi編譯器的內部部分,就像不可見過程一樣,當你聲明字符串或dynarray變量時,它們被隱式調用。

http://en.wikipedia.org/wiki/Intrinsic_function

像很多像_Write0LString程序正在實施通常WriteLn電話。

所以你將不得不做一個包裝函數,將打電話AssignFile並把您的包裝引用到您的變量,而不是;

然而,你沒有把標籤與你的Delphi版本,並且不同的vesions可能有不同的內在聲明。因此請查看您的特定Delphi的來源。

另外,你爲什麼需要它?我記得我在TurboPascal 5.5做了這樣的事情,使基於字符串的文件 - 使WriteLn行爲像C sprintf。但是,爲什麼你需要它在現代的德爾福,當你可以使用TStream而不是?

+0

您能否在TP5.5中發佈您的成功工作?它可能會給出一些線索...... – OnTheFly

+0

沒有。我在很遠的時候失去了它。它的主要價值在於反向工程數據類型,例如現在正式發佈的「文件」和「文本」(並且自那幾年以來發生了顯着變化)http://docwiki.embarcadero.com/Libraries/XE2/en/System.TFileRec http://docwiki.embarcadero.com/Libraries/XE2/en/System.TTextRec –

2

System.Assignintrinsic功能。它的official documentation是完全沒有希望的。它說:

function Assign(var F: File; FileName: String; [CodePage: Word]): Integer; overload; 
function Assign(var F: File; FileName: String; [CodePage: Word]): Integer; overload; 
function Assign(var F: File; FileName: String; [CodePage: Word]): Integer; overload; 

我只能猜測爲什麼文檔生成器不能應付這個功能。但是三個相同的超載顯然是虛假的。這不是一個功能,而是一個過程。

不管。因爲它是一個內在的,你不能把它分配給一個函數指針。解決方案是將其包裝在您自己的功能中。

procedure MyAssign(var F: File; const FileName: string); 
begin 
    Result := System.Assign(F, FileName); 
end; 

然後,您可以將該函數分配給過程類型的變量或常量。

const 
    AssignProc: procedure(var F: File; const FileName: string) = MyAssign; 

Assign其他變體採用指定的代碼頁,作爲Word傳遞的第三參數。如果Assign的第一個參數是TextFile,則只能調用該函數。

因此,內在性對他們自己來說確實是一種法律。

請注意,文檔確實不應再使用Assign。相反,你應該使用AssignFiledocumentation在這裏不是最好的!

+0

文檔非常具有誤導性,我嘗試了3個編譯器版本,並且都不允許將'Assign'作爲'function'調用。 – OnTheFly

+0

@ user539484是的,這裏的文檔非常糟糕。 –

+0

@DavidHeffernan似乎他們只是摧毀了他們的文檔,雖然我可以理解一些隨機轉換器的錯誤可能會導致這一點,我不明白爲什麼他們不能只是恢復MediaWiki的歷史!你怎麼會騙這個檢查:http://docwiki.embarcadero.com/Libraries/XE2/en/Vcl.StdCtrls.TComboBox_Properties(在XE3文檔中相同) - 屬性是在HTML源中,但他們故意隱藏 –

相關問題