デルファイの高階手順

Aug 22 2020

プロシージャを別のプロシージャのパラメータとして参照しようとしていますが、ドキュメントを理解するのに問題があります。(http://docwiki.embarcadero.com/RADStudio/Sydney/en/Procedural_Types_(Delphi))。

私が理解したことから、プロシージャの新しいタイプを作成する必要があります。

type
  TCallback = procedure of object;

高階手続きを次のように宣言します procedure HigherOrder(pProc: TCallback);

関数を呼び出そうとすると(ボタンがクリックされたとき)、コンパイルエラー「E2010互換性のないタイプ: 'TCallBack'および 'プロシージャ、型指定されていないポインタまたは型指定されていないパラメータ'」が表示されます。

type
  TCallBack = procedure of object;
  TfrmMain = class(TForm)
    btnAct: TButton;
    procedure btnActClick(Sender: TObject);
  private
    procedure HigherOrder(pProc: TCallback);
    procedure Callback();
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

{ TfrmMain }

procedure TfrmMain.btnActClick(Sender: TObject);
begin
  HigherOrder(Callback()); <--Error occurs here
end;

procedure TfrmMain.Callback;
begin
  //Do some stuff
end;

procedure TfrmMain.HigherOrder(pProc: TCallback);
begin
  //Do some other stuff
  pProc();
end;

end.

どんな助けでも大歓迎です。私はdelphiでのプログラミングにまったく慣れていません。

回答

11 RemyLebeau Aug 22 2020 at 14:32

問題は、最初に呼び出して Callback()から、その戻り値(これには戻り値がありません)をに渡そうとしていることですが、それは期待されてHigherOrder()いることではないHigherOrder()ため、エラーが発生します。言い換えれば、あなたのコードはこれとほぼ同等です:

procedure TfrmMain.btnActClick(Sender: TObject);
begin
  //HigherOrder(Callback());
  var res := Callback();
  HigherOrder(res);
end;

種類ことを除いresている未定義のため、がCallback()あるprocedureとありませんfunction

を呼び出すときは、パラメータの値としてそれ自体(とにかくそのメモリアドレス)を渡すためにHigherOrder()、末尾の()括弧を削除する必要があります。例:Callback()Callback pProc

procedure TfrmMain.btnActClick(Sender: TObject);
begin
  HigherOrder(Callback);
end;

はい、パラメータを渡さずにプロシージャを呼び出すときに括弧を削除することもできます。ただし、この場合、コンパイラーは、括弧を省略したCallbackIDがクロージャー型に割り当てられていることを認識できるほど賢いので、そのまま渡し、呼び出しません。