考虑一下:
const
clHotlight: TColor = $00FF9933;
clLink = clHotLight; //alias of clHotlight
[错误] file.pas:需要常量表达式
有效的替代措辞:
const
clHotlight = TColor($00FF9933);
clLink = clHotLight; //alias of clHotlight
请解释一下。
然后考虑一下:
const
AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
SuperuserGUID = AdministratorGUID; //alias of AdministratorGUID
[错误] file.pas:需要常量表达式
以及修复。
编辑:在声明之前添加了关键字
const
;有人不相信他们是常量。
clHotlight: TColor = $00FF9933;
不是常量,而是类型常量(=静态变量),即编译器在内存中为 TColor 保留一个槽,该槽将在运行时最初保存值 $00FF9933
。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
我尝试过这段代码:
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
你是对的:有些常数比其他常数更恒定。 第二个常量实际上被编译器视为变量。
clHotlight: TColor = $00FF9933;
^
通过
clHotlight
将 :
声明为“变量”(好吧,如果您在编译器选项中允许这样做,那么可以是“可分配常量”)。
正如您所发现的,声明:
clHotlight = TColor($00FF9933);
在稍后指定之前不分配
clHotlight
。
这同样适用于您的 GUID。
问题的出现是因为类型化常量并不是真正的常量,正如其他人以不同程度的清晰度和成功解释的那样。
尚未展示的是如何解决这个问题(在很多情况下),尽管有一对夫妇几乎要放弃这个秘密......:)
在您的具体情况下,您可以通过反转值的“别名”和类型化常量声明来解决问题,如下所示:
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 ) 等
阅读此处了解 Delphi 中的类型常量
常量声明的右侧必须是“常量表达式”,其定义为“常量表达式是编译器无需执行其所在程序即可计算的表达式”。您可以在语言指南中找到常量表达式的完整可接受语法。 请注意,语言指南明确指出“类型化常量不能出现在常量表达式中”。 - 这就是为什么你的声明失败,两个 clHotlight: TColor = $00FF9933;和管理员GUID:TGUID = ...;是类型常量。 此外,常量表达式不能包含除语言指南中列出的函数调用(即编译器能够在编译时计算的 Length()、SizeOf() 和其他一些函数调用)之外的函数调用。 这样重写:
const
AdminGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
AdministratorGUID: TGUID = AdminGUID;
SuperuserGUID: TGUID = AdminGUID;
它会起作用的。
欢迎来到德尔福进化。在delphi 1&2中,您不能将初始常量值分配给全局变量(例如:var xVar:Integer = 1)。您可以做到这一点的唯一方法是使用 const xVar: Integer = 1) 以及代码中的某些位置,然后您可以根据需要将其更改为其他内容。在他们摆脱这个古老的功能之前,您不能使用“const xVar:Integer”构造作为 const 值。
干杯 范