2010-02-20 36 views
16

我现在都这样了,它吮吸:德尔福数组初始化

type TpointArray = array [0..3] of Tpoint; 

class function rotationTable.offsets(pType, rotState, dir: integer): TpointArray; 
begin 

    Result[0] := point(1, 1); 
    Result[1] := point(1, 2); 
    Result[2] := point(1, 1); 
    Result[3] := point(1, 1); 
end; 

而是我想要做这样的事情:

class function rotationTable.offsets(pType, rotState, dir: integer): TpointArray; 
begin 
    Result := [Point(1,1), Point(1,2), Point(1,1), Point(1,1)]; 
end; 

但是,汇编,它抱怨说, [1,2,3,4]语法只能用于整数。

有没有一种方法来实例化/初始化类似于我想要的方式Tpoint的阵列?

回答

22

记录阵列可以在常量表达式intialised:

const 
    Points : TPointArray = ((X: 1; Y: 1), (X:1; Y:2), (X:1; Y:1), (X:1; Y:1)); 

class function rotationTable.offsets(pType, rotState, dir: integer): TpointArray; 
begin 
    Result := Points; 
end; 

在XE7就可以填补的记录,像这样的动态数组:

function GetPointArray: TArray<TPoint>; 
begin 
    Result := [Point(1,1),Point(1,2),Point(1,1),Point(1,1)]; 
end; 
+0

这不起作用(E2010 - 不兼容的类型)的D2006,直到我改变常量的定义'积分:TpointArray = ...' – yonojoy 2015-03-30 21:36:37

+0

感谢@yonojoy - 我可一直在使用的时候更高版本。 ''''而不是语法错误''' – 2015-03-30 22:00:16

+1

添加了一个XE7可能的例子,希望它可以:-) – 2015-03-30 23:05:46

4

你不能因为你不能表达码体在其中你可以表达它在const部分的方式点。

然而,你可以做一些技巧,让你的生活更轻松,尤其是如果你有合理数量的积分。

您可以实现这样一个简单的程序(未测试的代码):

procedure BlendDimensions(aXArray, aYArray: TIntegerDynArray; var aResult: TPointArray); 
var 
    nCount: integer; 
    i: integer; 

begin 
    nCount:=High(aXArray); 
    if nCount <> High(aYArray) then 
    Exception.Create('The two dimension arrays must have the same number of elements!'); 

    SetLength(aResult, nCount); 
    for i:=0 to nCount do 
    begin 
    aResult[i].X:=aXArray[i]; //simple copy 
    aResult[i].y:=aYArray[i]; 
    end; 
end; 

...其中TIntegerDynArray是RTL的整数动态数组。 (实际上它可以和任何动态数组一起使用)。另外,上例中的TPointArray也是动态的。

因此,为了做你的工作,你可以这样做:

procedure Foo; 
var 
    myXCoords, myYCoords: TIntegerDynArray; //temp arrays 
    myPoints: TPointArray; //this is the real thing 

begin 
    myXCoords:=TIntegerDynArray.Create(1, 2, 3, 4, 5, 6, 7, 8, 9,10); 
    myYCoords:=TIntegerDynArray.Create(21,32,34,44,55,66,65,77,88,92); //...for example 
    BlendDimensions(myXCoords, myYCoords, myPoints); //build the real thing 
//use it... 
end; 

注意事项:

  • 你清楚地看到这是你的分
  • 你可以非常有效这样生产
  • 您也可以在其他东西上使用BlendDimensions不仅在这个
  • 您可以轻松扩展3个(或更多)尺寸的BlendDimensions
  • ...但要小心,因为涉及副本。 :-)对于今天的个人电脑,目前的弱点将是你的手。 :-)你会厌倦打字速度更快,直到复制时间甚至会被注意到。

HTH

+0

我不知道这个“数组构造函数”是否可以用于“数组记录” – 2012-12-18 07:31:07

8

Plainth's answer演示动态数组构造的语法。您可以直接使用一个TPoint阵列上,以产生一个更简单的辅助函数:

type 
    TPointDynArray = array of TPoint; 
    T4PointArray = array[0..3] of TPoint; 

function PointDynArrayTo4PointArray(const input: TPointDynArray): T4PointArray; 
var 
    i: Integer; 
begin 
    Assert(Length(input) = Length(Result)); 
    for i := 0 to High(input) do 
    Result[i] := input[i]; 
end; 

class function rotationTable.offsets(pType, rotState, dir: integer): T4PointArray; 
begin 
    // New dynamic-array-constructor syntax here 
    Result := PointDynArrayTo4PointArray(TPointDynArray.Create(
    Point(1,1), Point(1,2), Point(1,1), Point(1,1))); 
end; 

但是,这是矫枉过正。 Delphi还允许你定义开放数组内联,并且没有额外的构造函数调用来编写。结果使用你原来建议的语法,但是数组包装在一个函数调用中。它将适用于所有的Delphi版本,而上面的“Create”语法是相当新的。

function PointOpenArrayTo4PointArray(const input: array of TPoint): T4PointArray; 
var 
    i: Integer; 
begin 
    Assert(Length(input) = Length(Result)); 
    for i := 0 to High(input) do 
    Result[i] := input[i]; 
end; 

class function rotationTable.offsets(pType, rotState, dir: integer): T4PointArray; 
begin 
    Result := PointOpenArrayTo4PointArray(
    [Point(1,1), Point(1,2), Point(1,1), Point(1,1)]); 
end; 

你可能要考虑使用Gerry's answer只是给你点有意义的名称,调试,并在这些点定义八个幻数的一个是错误的,当它可能帮助的阵列。


最后,关于Delphi在表示“[1,2,3,4]语法只能用于整数”时的含义。该语法定义了一个集合,而不是一个数组。你不能有一组记录值,但你的可以有有一组整数。副作用是一组整数的语法与一个打开的整数数组的语法相同。我认为德尔福使用上下文来弄清楚你的意思,但它有时会猜错。