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在声明前添加关键字;有人不相信他们是常量。

4

7 回答 7

23

clHotlight: TColor = $00FF9933;不是常量,而是类型化常量(=静态变量),即编译器在内存中为 TColor 保留一个插槽,该插槽将$00FF9933在运行时初始保存该值。
因为该值可以在以后更改(使用 Assignable Const 选项 ON),所以它不是一个实常数并且不能被编译器接受clLink = clHotLight;

clHotlight = TColor($00FF9933);与它是一个真正的常量严格相同,clHotlight = $00FF9933;
编译器将用clHotlight它的值替换$00FF9933它出现在代码中的任何位置。也是clLink如此。

阅读这个 SO 问题(在 Delphi 7 中,为什么我可以为 const 赋值?)以及那里所有的好答案......

编辑:关于 TGUID ......
问题是写作AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';不正确。
它使用一些编译器魔法StringToGUID在幕后调用,从而可以方便地将 GUID 表达为字符串,而它们本质上不是字符串。它们是记录。

所以,尝试是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 

你是对的:一些常数比其他常数更恒定。第二个常量实际上被编译器视为一个变量。

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

Is declaring clHotlight as a 'variable' (well, ok an 'assignable constant' if you've permitted this in compiler options) by means of the :.

As you've found, declaring:

clHotlight = TColor($00FF9933); 

Makes no allocation of clHotlight until it is specified later.

The same applies to your 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 常量在所有需要TGUID的地方都非常有用,例如IsEqualGUID ( tguid, GUID_CONSTANT ) 等。

于 2010-04-26T21:18:00.543 回答
3

阅读此处了解 Delphi 中的类型化常量

于 2010-04-26T15:00:51.293 回答
2

常量声明的右侧必须是“常量表达式”,它被定义为“常量表达式是编译器可以在不执行它出现的程序的情况下计算的表达式”。您可以在语言指南中找到常量表达式的全部可接受语法。请注意,语言指南明确指出“类型化的常量不能出现在常量表达式中”。- 这就是你的声明失败的原因,两者都是 clHotlight: TColor = $00FF9933; 和管理员GUID:TGUID = ...;是类型化的常量。此外,常量表达式不能包括编译器能够在编译时计算的语言指南中列出的函数调用(即 Length()、SizeOf() 和其他一些函数)。这样重写:

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

它会起作用。

于 2010-04-27T07:38:27.143 回答
1

欢迎来到德尔福进化。在 delphi 1 和 2 中,您不能将初始常量值分配给全局 var(例如:var xVar: Integer = 1)。您可以做到这一点的唯一方法是使用 const xVar: Integer = 1) 以及代码中的某些位置,然后您可以根据需要将其更改为其他内容。在他们摆脱这个古老的特性之前,您不能使用“const xVar: Integer”构造作为 const 值。

干杯范

于 2010-04-26T19:13:32.543 回答