1

FreePascalとLazarusは初めてです。新しい「高度なレコード」機能をテストしていて、不要なコンパイラ警告のように見えるものを取得しています。

コードは非常に単純で、データフィールドを初期化するための単一のメソッドを持つレコードです。何かのようなもの:

{$mode delphi}

type TTest =
  record
    a,b: double;
    procedure Init(x,y: double);
  end

procedure TTest.Init(x,y: double);
begin
  test.a := x;
  test.b := y;
end;


var t: TTest;
begin
  t.Init(0.1,0.2);

示されている最後の行「t.Init()」は、常に「変数「t」が初期化されていないように見える」というコンパイラ警告を生成します。

わかりました、それは警告にすぎないので、明らかに私はそれと一緒に暮らすことができますが、それが私の側の根本的な誤解によるものではないことを確認したいだけです。


編集して新しい情報を追加します。

メソッドとコンストラクターのポイントを再確認してください。これをもう少し調べてみると、FPCがレコードのコンストラクターを許可していないのはうれしいです。Delphiにはコンストラクタはありますが、デストラクタはありません。私が知る限り、コンストラクタ(レコード用)は、メソッドが実行できないことをまったく実行しません。私はミニマリストなので、既存の構文よりも何もしない追加の構文を使用する意味はありません。

特にこのような単純なレコードの場合、それを宣言するという行為(var t:TTest)は、このレコードに必要なすべての「構築」を行います。他のもの(私のInitのような)は値を設定するだけで、とにかく何も構築していません。コンストラクターが答えではないことがわかる限り、コンパイラーは警告をドロップする必要があります。

この問題を調査すると、よく使用されるもう1つの手法、いわゆる「ファクトリ関数」に出くわしました。つまり、次のようなレコード外の関数です。

function InitTTest(x,y: double): TTest;
begin
  Result.a := x;
  Result.b := y;
end;

この手法は実際に機能し、警告メッセージを取り除きます。しかし、私はこの方法が好きではなく、使用しません。高度なレコードには、クラスの継承やその他の機能はありません。カプセル化がすべてです。ですから、このようなレコードの外に「ファクトリー関数」を作成するのは本当に嫌いです。

ここで私自身の質問に答えるために少し調査を行った後、上記は単なる「初心者」の意見であることを覚えておいてください。ですから、上記のことについて間違っていた場合は、訂正できてとてもうれしく思います。:)

4

1 に答える 1

3

はい、それがコンストラクターの目的です。以下はFPCトランクでコンパイルされ、警告は生成されません。

{$mode delphi}

type TTest =
  record
    a,b: double;
    constructor Init(x,y: double);
  end;

constructor TTest.Init(x,y: double);
begin
  a := x;
  b := y;
end;


var t: TTest;
begin
  t.Init(0.1,0.2);
end.
于 2013-03-16T18:24:20.677 に答える