2010-02-20 55 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]語法只能用於整數」時的含義。該語法定義了一個集合,而不是一個數組。你不能有一組記錄值,但你的可以有有一組整數。副作用是一組整數的語法與一個打開的整數數組的語法相同。我認爲德爾福使用上下文來弄清楚你的意思,但它有時會猜錯。