-2

残念ながら、正確なAssign署名は RTL ソースでは利用できず、次のように推測しようとしています。

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 と正確に一致させるには、どの型を使用すればよいでしょうか。

4

3 に答える 3

4

Assignは、その起源を元の Turbo Pascal 構文にまでさかのぼる Delphi の言語名残です。関数のオーバーロードが言語構文に追加されるずっと前、RTL のテキスト ファイルと「ファイル タイプ」の内部データ構造が文書化されるずっと前に、Assign.

Assign使用するのに十分単純な手順ですが、それが何をしなければならないかを見ると、ある種のコンパイラマジックなしでは実装することはほとんど不可能であることがわかります. File of TFooとは異なり、互換性のないファイル タイプを作成しますFile of Integer。それでも、両方を の最初のパラメーターとして渡すことができますAssign

今日では、おそらくAssignfile パラメーターのジェネリック型パラメーターを使用して実装できます。ジェネリック型は、渡された変数の型に準拠します。それは素晴らしいことですが、ジェネリックがミックスに追加される 25 年前に、型付きファイル変数を文字列ファイル名に関連付ける方法が必要でした。

Assignコンパイラ組み込み関数です。つまり、Delphi/Pascal 構文空間の外にあるということです。Assignは本質的に型準拠の手続きであり、厳密に型指定された Delphi/Pascal 言語では表現できません(ジェネリック型などの現代的で複雑な言語拡張なしでは)。実際のパラメーターの型はコンパイル時に完全に決定されるため、型なしではなく、動的に型指定されません。

関数のアドレスを取得することはできませんAssign。できたとしても、それは不定形であるため、可能なすべての呼び出しシグネチャを正確に表すプロシージャ型を定義することはできません。

コンパイラの魔法の関数は言語の外に存在し、当時利用可能な構文では簡単に表現できなかったタスクを処理します。Assignは一例です。Writeln() は別のものです。

于 2013-04-15T19:01:33.957 に答える
2

System.Assign固有関数です。それの公式文書は完全に絶望的です。それは言います:

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;

ドキュメントジェネレーターがこの機能に対応できない理由については推測することしかできません。しかし、3 つの同一のオーバーロードは明らかに偽物です。これは関数ではなく、手続きです。

どんなに。これは組み込みであるため、関数ポインターに割り当てることはできません。解決策は、独自の関数でラップすることです。

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;

のもう 1 つのバリアントはAssign、コード ページを指定する 3 番目のパラメータを として渡しますWord。への最初の引数AssignTextFile.

したがって、組み込み関数は実際にはそれ自体が法則です。

Assignドキュメントには、使用すべきではないと記載されていることに注意してください。代わりに を使用する必要がありますAssignFileドキュメンテーションはそれほど良くありません。

于 2013-04-15T16:10:31.313 に答える
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;

そして、名前にアンダースコアのないグローバルな安定したプロシージャはないと思います-リストされているのは、文字列またはdynarray変数を宣言するときに密かに呼び出される、目に見えないプロシージャのようなDelphiコンパイラの内部です。

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

_Write0LString通常の WriteLn 呼び出しを実装しているような多くの手順と同様です。

そのため、代わりにラッパーへの参照を呼び出しAssignFileて変数に入れるラッパー関数を作成する必要があります。

ただし、Delphi バージョンにタグを付けていないため、異なるバージョンでは組み込み関数の宣言が異なる場合があります。特定の Delphi のソースを調べてください。

また、なぜそれが必要なのですか?TurboPascal 5.5文字列ベースのファイルを作成するためにそのようなことをしたことを覚えています-makeはWriteLnC のように振る舞いますsprintfTStreamしかし、代わりに使用できるのに、なぜ現代の Delphi でそれが必要になるのでしょうか?

于 2013-04-15T14:12:57.620 に答える