考虑:
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
;有人不相信他们是常数。
答案 0 :(得分:23)
clHotlight: TColor = $00FF9933;
不是常量而是类型常量(=静态变量),即编译器在内存中为TColor保留一个插槽,该插槽最初将在运行时保存值$00FF9933
。 />
因为稍后可以更改该值(使用Assignable Const选项为ON),它不是真正的常量,并且clLink = clHotLight;
clHotlight = TColor($00FF9933);
与clHotlight = $00FF9933;
严格相同
它是一个真正的常量,编译器会将clHotlight
替换为值$00FF9933
,无论它出现在代码中的哪个位置。对于clLink
也是如此。
阅读这个SO问题(In Delphi 7, why can I assign a value to a const?)以及那里的所有好答案......
编辑:关于TGUID ......
问题是写AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
是不合适的
它正在使用一些编译器魔法来调用场景后面的StringToGUID
,这样可以方便地将GUID表示为字符串,而这些字符串本质上不是。他们是记录。
因此,尝试AdministratorGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
将无效。那不是GUID ......
解决方法是使用 absolute
指令将类型常量和变量指向同一内存区域:< / p>
const
AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
var
SuperuserGUID: TGUID absolute AdministratorGUID; //alias of AdministratorGUID
RootGUID: TGUID absolute AdministratorGUID; //alias of AdministratorGUID
答案 1 :(得分: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 :(得分:5)
clHotlight: TColor = $00FF9933;
^
通过clHotlight
将:
声明为'变量'(好吧,如果您已在编译器选项中允许,则可以使用'可分配常量') 。
如你所见,宣布:
clHotlight = TColor($00FF9933);
在clHotlight
之前未指定之前不进行分配。
这同样适用于您的GUID。
答案 3 :(得分: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)等。
答案 4 :(得分:3)
答案 5 :(得分:2)
常量声明的右侧必须是“常量表达式”,它定义为“常量表达式是编译器可以在不执行其出现的程序的情况下进行求值的表达式”。您可以在语言指南中找到用于常量表达的完整语法。 请注意,语言指南明确指出“类型常量不能出现在常量表达式中”。 - 这就是你的声明失败的原因,clHotlight:TColor = $ 00FF9933;和AdministratorGUID:TGUID = ...;是类型常量。 此外,常量表达式不能包括函数调用,除了语言指南中列出的函数调用(即Length(),SizeOf()和其他一些函数),编译器能够在编译时计算它们。 用这种方式改写:
const
AdminGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
AdministratorGUID: TGUID = AdminGUID;
SuperuserGUID: TGUID = AdminGUID;
它会起作用。
答案 6 :(得分:1)
干杯 Pham