传递记录参数而不首先将其声明为变量

时间:2012-01-15 07:02:05

标签: delphi delphi-xe2

如果我试图调用一个记录类型(不是对象)作为参数的过程,是否可以以某种方式传递该参数“inline”的细节而不必先声明该类型的变量?

例如假设我有这种简单的记录类型:

type TMyRecord = record
  AString: string;
  AnInt: Integer;
end;

和此程序声明:

procedure MyProcedure(Rec: TMyRecord);

如果我想调用MyProcedure,我是否必须声明TMyRecord类型的变量,或者我可以执行以下操作:

MyProcedure(TMyRecord("Test", 10));

这不起作用(XE2)(得到关于它的编译器错误,期待“)”。

那么,我可以这样做吗?或者不可能。

由于

4 个答案:

答案 0 :(得分:17)

可以使用advanced record结构。

有关advanced records的详细信息,请参阅Delphi帮助中的Records (advanced) section

这是一个小型原型,可以看到它在您的情况下如何在函数/过程调用中预初始化记录:

Type
  TRecord = record
   AString : String;
   AnInt : Integer;
   Constructor Create( Const s : String; i : Integer);
  end;

constructor TRecord.Create(const s: String; i: Integer);
begin
  AString := s;
  AnInt := i;
end;

procedure DoSomething( theRec : TRecord);
begin
  WriteLn(theRec.AString, ' ',theRec.AnInt);
end;

begin
  DoSomeThing( TRecord.Create('S',1));
  ReadLn;
end.

查看Delphi RTL,请参阅单元TPoint(XE2)中记录类型TRectsystem.types的定义。 它们定义了一些重载的Create构造函数,它们在很多地方用于预处理函数/过程调用中的记录结构。

答案 1 :(得分:17)

您要问的问题与代码可读性有关,并且有一个避免必须创建变量的解决方案。 VCL将此解决方案与记录TPointTRect一起使用。

考虑TPoint

的定义
type
  TPoint = record
    X,Y integer
  end;

TPoint传递给您可能执行的程序:

var
  MyPoint : TPoint;

begin
  MyPoint.X := 5;
  MyPoint.Y := 7;
  DoSomething( MyPoint );
end;

这很好但是当使用工厂函数Point

时也可以使用3行
begin
  DoSomething( Point(5,7) );
end;

在Delphi中,函数声明如下:

function Point( X, Y : integer ) : TPoint;
begin
  Result.X := X;
  Result.Y := Y;
end;

然后,您可以将此函数称为“内联”以快速创建“即时”记录 您将看到TRect等已经提供了相同的内容。我经常将这样的工厂功能与记录声明一起放在下面,即使我不打算使用它们:

type
  TMyRecord = record
    A : integer;
    B : string;
  end;

function MyRecord( A : integer; const B : string ) : TMyRecord;
begin
  Result.A := A;
  Result.B := B;
end;

使用此技术可以提高代码的可读性,还可以确保您不会意外地省略设置记录元素。

答案 2 :(得分:5)

只是玩约翰伊斯利的想法:

type TRec = record
  X: string;
  Y: Integer;
end;

procedure TestRec(const Rec: array of const);
var
  R: TRec;

begin
  R.X:= string(Rec[0].VUnicodeString);
  R.Y:= Rec[1].VInteger;
  ShowMessage(R.X + IntToStr(R.Y));
end;

procedure TForm1.Button7Click(Sender: TObject);
begin
  TestRec(['Test', 22]);
end;

可以将记录字段作为array of const参数传递,并将这些参数分配给本地记录变量。

答案 3 :(得分:3)

太棒了!但是,没有。

如果直接传递内联确实是你的目标,那么开放数组参数可能适合你。

Procedure MyProcedure(const Vars: Array of Variant);
begin
  ShowMessage(VarToStr(Vars[0])+'  '+VarToStr(Vars[1]));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   MyProcedure(['Test', 12]);
end;

你也可以传递一个Const数组,它基本上是一个TVarRec数组,它是一个变体记录,它还包括VType类型信息。这很有趣......

这里有一篇优秀的文章可以在Rudy的Delphi Corner找到: Rudy's Delphi Corner, Open Array Parameters