簡體   English   中英

Delphi數組初始化

[英]Delphi array initialization

我目前有這個,它很糟糕:

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數組,類似於我想要的方式?

記錄數組可以在const表達式中初始化:

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;

Plainth的答案演示了動態數組的類似構造函數的語法。 您可以直接在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的答案,只是為了給點數組提供有意義的名稱,這在調試時可能會有所幫助,並且這些點定義中的八個幻數之一是錯誤的。


最后,說明Delphi在說“[1,2,3,4]語法只能用於整數時”的含義。 該語法定義了一個集合 ,而不是一個數組。 您不能擁有一組記錄值,但可以擁有一組整數。 副作用是一組整數的語法與打開的整數數組的語法相同。 我認為Delphi使用上下文來確定你的意思,但它有時會猜錯。

你不能因為你不能在代碼體中表達你在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
  • 您可以輕松地將BlendDimensions擴展為3個(或更多)維度
  • ...但請注意,因為涉及到副本。 :-)對於今天的PC,到目前為止,弱點將是你的手。 :-)你會很累,輸入更快,直到復制時間被注意到。

HTH

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM