【问题标题】:Delphi array initializationDelphi 数组初始化
【发布时间】:2010-02-20 03:24:12
【问题描述】:

我目前有这个,但很糟糕:

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 数组?

【问题讨论】:

    标签: delphi arrays point tobject


    【解决方案1】:

    记录数组可以在 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;
    

    【讨论】:

    • 这在 D2006 中不起作用(E2010 - 不兼容的类型),直到我将常量的定义更改为 Points : TpointArray = ...
    • 感谢@yonojoy - 当时我可能一直在使用更高版本。 , 而不是 ; 也有语法错误
    • 添加了 XE7 可能的示例,希望没问题 :-)
    【解决方案2】:

    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 版本,而上面的“创建”语法是相当新的。

    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] 语法只能用于整数。”该语法定义了一个set,而不是一个数组。你不能有一组记录值,但你可以有一组整数。副作用是一组整数的语法与开放整数数组的语法相同。我认为 Delphi 使用上下文来确定您的意思,但它有时会猜错。

    【讨论】:

      【解决方案3】:

      你不能,因为你不能在代码主体中表达你可以在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

      【讨论】:

      • 我想知道这个“数组构造函数”是否可以用于“记录数组”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多