10

假设您有一个要初始化的本地记录:

type 
  TMyRec=record
    Val1, Val2:Integer;
  end;

procedure MyProc;
var
  MyVar:TMyRec;
begin
  // ... ?

  WriteLn(Val1,Val2);
end;

除了“手动”设置每个字段外,还有几种方法可以做到这一点。

  1. 使用初始化():

    Initialize(MyVar);
    
  2. 使用默认():

    MyVar := Default(TMyVar);
    
  3. 使用FillChar

    FillChar(MyVar,SizeOf(MyVar),0);
    
  4. 定义一个空常量,并将其分配给 var

    const cMyVar:TMyVar=();  
    ...    
    MyVar := cMyVar;    
    

以上所有似乎都适用于这个例子的情况。我猜你甚至可以定义一个全局变量来初始化它。

但是有没有首选的方法?或者在某些情况下不建议使用上述任何一种,或者它根本不起作用?

简而言之,初始化本地堆栈变量明确正确方法是什么?:-)

4

1 回答 1

14

永远不要Initialize用于局部变量。

Initialize 只能在 Delphi 代码中使用,其中变量是通过 New 标准过程以外的其他方式动态分配的。

更重要的是,由于它不包含任何托管类型,因此它会被优化为带有您的记录的 nop。所以,我们可以放弃这个选项,将场地减少到三个竞争者。

其余三个竞争者对未初始化的局部变量都有相同的效果。但是,FillChar在带有托管成员的局部变量上使用是有风险的,例如字符串、接口引用、变体等。如果托管成员已被初始化,那么您将破坏引用计数机制。但是,如果您确定该记录尚未初始化,那么FillChar它是安全有效的,尽管在我看来相当难看。就个人而言,我会拒绝FillChar这个角色。

剩下Default(T)的就是不断的赋值。在旧版本的 Delphi 中,您只能使用常量赋值。可以公平地说,当FillChar您声明常量时,常量赋值与 一样难看。因此,在我看来,在现代 Delphi 版本中,我会选择它,Default()因为它更简洁且可读性更好。

正如在涵盖类似基础的问题中所讨论的那样,Default(T)当您分配给变量时,编译器会生成非常高效的代码。

于 2013-01-05T21:11:21.877 回答