22

検討:

const 
   clHotlight: TColor = $00FF9933;
   clLink = clHotLight; //alias of clHotlight

[Error] file.pas: Constant expression expected

そして、機能する別の言い回し:

const 
   clHotlight = TColor($00FF9933);
   clLink = clHotLight; //alias of clHotlight

説明。


次に、次のことを検討してください。

const 
   AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
   SuperuserGUID = AdministratorGUID; //alias of AdministratorGUID

[Error] file.pas: Constant expression expected

そして修正します。

編集:const宣言の前にキーワードを追加しました。誰かが彼らがconstであると信じていませんでした。

4

7 に答える 7

23

clHotlight: TColor = $00FF9933;は定数ではなく、型付き定数(=静的変数)です。つまり、コンパイラ$00FF9933は、実行時に最初に値を保持するTColor用のスロットをメモリに予約します。
その値は後で(Assignable Constオプションをオンにして)変更できるため、実際の定数ではなく、コンパイラで受け入れることはできません。clLink = clHotLight;

clHotlight = TColor($00FF9933);これはclHotlight = $00FF9933;
真の定数であり、コンパイラはコード内のどこにある場合でもclHotlightその値に置き換えます。$00FF9933そしてclLink同様に。

このSOの質問(Delphi 7では、なぜconstに値を割り当てることができるのですか?)とそこにあるすべての良い答えを読んでください...

編集:TGUIDについて...
問題は、書き込みAdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';が適切でないことです。コンパイラの魔法
を 使って舞台裏で呼び出し、GUIDを本来ではない文字列として表現するのに便利です。それらは記録です。StringToGUID

したがって、試行しても機能しAdministratorGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';ません。それはGUIDではありません...

回避策は、ディレクティブ を使用して、型指定された定数変数が同じメモリ領域を指すようにすることです。absolute

const
   AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
var
   SuperuserGUID: TGUID absolute AdministratorGUID; //alias of AdministratorGUID
   RootGUID: TGUID absolute AdministratorGUID;      //alias of AdministratorGUID
于 2010-04-26T17:08:57.637 に答える
7

私はこのコードを試しました:

  const
    CAnswer1 = 42;
    CAnswer2 : Integer = 42;

  var
    LAnswer : Integer;

  begin
    LAnswer := CAnswer1;
    LAnswer := CAnswer2;
  end;

生成されたコードは次のとおりです。

Project9.dpr.18: LAnswer := CAnswer1;
004101AC C7056C6E41002A00 mov [$00416e6c],$0000002a //<- assign a hard-coded "42" value
Project9.dpr.19: LAnswer := CAnswer2;
004101B6 A1701C4100       mov eax,[$00411c70] //<- fetch a variable's content
004101BB A36C6E4100       mov [$00416e6c],eax //<- assign this content 

あなたは正しいです:いくつかの定数は他のものより一定です。2番目の定数は、実際にはコンパイラーによって変数として扱われます。

于 2010-04-26T16:13:17.950 に答える
5
clHotlight: TColor = $00FF9933; 
          ^

clHotlightを使用して、「変数」として宣言しています(コンパイラオプションでこれを許可している場合は、「割り当て可能な定数」を使用できます):

あなたが見つけたように、宣言します:

clHotlight = TColor($00FF9933); 

clHotlight後で指定されるまで、の割り当ては行われません。

同じことがGUIDにも当てはまります。

于 2010-04-26T14:57:07.760 に答える
4

問題が発生するのは、他の人がさまざまな程度の明快さと成功で説明しているように、型付き定数が実際には定数ではないためです。

まだ示されていないのは、問題を回避する方法です(多くの場合)が、カップルはその秘密をあきらめることに興味をそそるほど近づいていました... :)

特定のケースでは、次のように値の「エイリアシング」と型付き定数宣言を逆にすることで問題を回避できます。

const
  clLink = $00FF9933;
  clHotlight: TColor = clLink;

clLinkは真の定数を提供するようになり、clHotlightはclLinkと同じ値を持つ型付き定数です。

GUIDについても同じ手法を使用できますが、型指定されたGUID定数を初期化するために使用される通常の定数式を覚えておく必要があります。レコードは使用せず、単純なリテラル文字列を使用するため、次のようになります。

const
  ID_CONSTANT = '{AA1C8AF2-C290-40AB-9CF5-2888A46E1660}';
  GUID_CONSTANT: TGUID = ID_CONSTANT;

注:このようなGUID定数は、 IsEqualGUID(tguid、GUID_CONSTANT)など、TGUID必要なすべての場所で完全に使用できます。

于 2010-04-26T21:18:00.543 に答える
3

ここを読むDelphiで型付き定数を理解する

于 2010-04-26T15:00:51.293 に答える
2

定数宣言の右側は「定数式」である必要があります。これは、「定数式は、それが発生するプログラムを実行せずにコンパイラーが評価できる式です」と定義されています。定数式で受け入れられている構文全体は、言語ガイドに記載されています。言語ガイドには、「型付き定数は定数式では使用できない」と明示的に記載されていることに注意してください。-そしてそれがあなたの宣言が失敗する理由です、両方ともclHotlight:TColor = $ 00FF9933; およびAdministratorGUID:TGUID = ...; 型付き定数です。また、定数式には、コンパイラがコンパイル時に計算できる言語ガイドにリストされているもの(つまり、Length()、SizeOf()など)以外の関数呼び出しを含めることはできません。次のように書き直します。

const
  AdminGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
  AdministratorGUID: TGUID = AdminGUID;
  SuperuserGUID: TGUID = AdminGUID;

そしてそれは動作します。

于 2010-04-27T07:38:27.143 に答える
1

Delphiの進化へようこそ。delphi 1および2では、初期定数値をグローバル変数に割り当てることはできません(例:var xVar:Integer = 1)。これを行う唯一の方法は、const xVar:Integer = 1)を使用することです。コードのどこかで、必要に応じてそれを他の何かに変更できます。彼らがこの古代の機能を取り除くまで、const値として「constxVar:Integer」構文を使用することはできません。

乾杯ファム

于 2010-04-26T19:13:32.543 に答える