Delphi如何将变量分配给常量?

4
这个网站:http://www.drbob42.com/delphi/wizards.htm,底部显示了一段非常令人困惑的代码。
 unit ShareMem;
 { (c) 1997 by Bob Swart (aka Dr.Bob - http://www.drbob42.com }
 interface

 const
...
 uses
   Windows;

 const
   Handle: THandle = 0;
...
 function GetCommandLine: PChar; stdcall;
   external 'kernel32.dll' name 'GetCommandLineA';
...
   begin
     Handle := LoadLibrary('BCBMM.DLL');
 end.

这怎么可能呢?

可能是 In Delphi 7, why can I assign a value to a const? 的重复问题。 - Rob Kennedy
3个回答

7

Delphi有一种叫做可分配常量的东西,可以允许给const赋值。这可以通过编译器指令和开关来打开/关闭。如果需要更详细的解答,请参见这里

在类属性成为可能之前,它有时会派上用场。即使常量在函数内部声明,它也会在调用之间保持其值。

procedure Test;
{$WRITEABLECONST ON}
const
  AssignableConst: Integer = 0;
{$WRITEABLECONST OFF}
begin
  AssignableConst := AssignableConst + 1; 
  WriteLn('Test is called ' + IntToStr(AssignableConst) + ' times'); 
end;

3
应该写成 WriteLn('测试被调用了 '+ IntToStr(AssignableConst) + ' 次'); 祝好。 - RBA
抱歉,我想我花了太多时间在C#上了。已经修复了。谢谢。 - Lars Truijens

4

默认情况下,一个带有 const 类型的变量(注:如评论中Rob所指出的,这个默认值已经在多年前改变了)更像是一个静态变量。您可以通过编译器指令关闭此行为

在旧版本的Delphi中,这通常被用作 class/static properties 的替代方法。现在Delphi实际上已经具备了这个功能,我认为没有好的理由再这样做。


你能否在回答中添加一个链接,解释一下Delphi当前类静态特性? - none
Craig,可写性的默认值在很多版本前就已经改变了(我想是在D7中)。但即使编译器禁止对它们进行赋值语句,它们仍然像静态变量一样。它们始终有地址,并且在常量表达式中仍然不允许使用。可写类型常量并没有真正被类变量所取代。我们从来没有需要在单元级别范围内使用可写类型常量;我们一直可以在那里使用普通变量。可写类型常量仍然有用的地方是用于局部静态变量。 - Rob Kennedy
1
@Rob,关于默认值的观点很好;我会更新的。关于实现细节,你是对的,但我不认为他在问那个。我喜欢可分配常量的减少范围,但我不认为这个问题所表现出来的可读性痛苦是值得的,所以我不使用它们作为本地静态变量;我只是没有那个功能而已。 - Craig Stuntz

1
你想了解的是一个可写类型常量。自 Turbo Pascal 早期起,可写类型常量就已经存在了。事实上,这是声明初始化变量的唯一方法。在内部,可写类型常量和初始化变量是等效的,都进入DATA段(这就是Lars Truijens的例子的工作原理)。此外,类型常量可以保存不允许真正常量拥有的数据类型,这才是它们真正的语义目的。自 Delphi 4(甚至是3?)以来,Borland 意识到混合使用常量和变量的方式很奇怪,并引入了初始化全局变量$WRITEABLECONST 开关指令(默认为OFF)。初始化变量不能出现在本地范围内,因此仍然需要可写类型常量存在。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接