【发布时间】:2011-09-14 09:11:59
【问题描述】:
看起来 Delphi 编译器在以下情况下不支持 const 记录参数 涉及“记录方法”。
之前没有尝试滥用 const 约定,我有点惊讶 找到编译器接受的代码:
type
TTest = record
Field : String;
procedure Update;
end;
procedure TTest.Update;
begin
Field := Field + '+1';
end;
procedure DoStuff(const t : TTest);
begin
ShowMessage(t.Field);
t.Update;
ShowMessage(t.Field);
end;
如果你尝试做一个
t.Field:='doh'; in DoStuff f.i.,编译器会正确地抱怨,但你可以调用修改“const”记录的方法,甚至没有提示或警告。因此,这与引用类型(例如类或动态数组)的行为不同,后者允许直接字段写入(因为 const 仅限制对参数本身的更改)。
附录:这也允许以这种方式修改声明的编译时常量,如:
const
cTest : TTest = (Field : '1');
...
cTest.Update; // will show '1' then '1'+'1'
ShowMessage(cTest.Field); // will show '1' (because optimized at compile-time)
这是一种公认的/记录在案的行为吗?还是只是编译器的缺点?
【问题讨论】:
-
我更新了附录以直接调用
Update方法,因为在我看来这是这里的根本问题。您需要记录的方法来改变 const 记录。 -
恕我直言,这里真正的错误是
Update。 Value types should be used as immutable。 (链接是 C# 示例,抱歉,但想法是一样的。)另见 this SO answer。 -
@David,您对附录的编辑使该示例无效。直接调用
Update会修改字段值,但我们看不到该更改的结果,因为编译器显然在随后的ShowMessage语句中优化了对它的直接访问。 -
@Rob 我的编辑是在
ShowMessage之前进行的,并进行了优化。在我进行编辑时,我认为这是合理的。 -
DoStuff 在编辑前故意在示例中,以表明在实践中它可能发生在不明显的情况下。