如果我试图调用一个记录类型(不是对象)作为参数的过程,是否可以以某种方式传递该参数“inline”的细节而不必先声明该类型的变量?
例如假设我有这种简单的记录类型:
type TMyRecord = record
AString: string;
AnInt: Integer;
end;
和此程序声明:
procedure MyProcedure(Rec: TMyRecord);
如果我想调用MyProcedure,我是否必须声明TMyRecord类型的变量,或者我可以执行以下操作:
MyProcedure(TMyRecord("Test", 10));
这不起作用(XE2)(得到关于它的编译器错误,期待“)”。
那么,我可以这样做吗?或者不可能。
由于
答案 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)中记录类型TRect
和system.types
的定义。
它们定义了一些重载的Create
构造函数,它们在很多地方用于预处理函数/过程调用中的记录结构。
答案 1 :(得分:17)
您要问的问题与代码可读性有关,并且有一个避免必须创建变量的解决方案。 VCL将此解决方案与记录TPoint
和TRect
一起使用。
考虑TPoint
:
type
TPoint = record
X,Y integer
end;
将TPoint
传递给您可能执行的程序:
var
MyPoint : TPoint;
begin
MyPoint.X := 5;
MyPoint.Y := 7;
DoSomething( MyPoint );
end;
这很好但是当使用工厂函数Point
:
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