2010-02-20 21 views
16

Actualmente tengo esto, y es una mierda:Delphi inicialización del campo

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; 

pero en cambio, quiero hacer algo como esto:

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

Sin embargo, en la compilación, se queja de que la sintaxis [1, 2, 3, 4] solo puede funcionar para enteros.

¿Hay alguna manera de instanciar/inicializar una matriz de Tpoint similar a la que yo quiero?

Respuesta

22

matrices de registros se pueden intialised en expresiones 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; 

En XE7 es posible llenar una matriz dinámica de los registros de la siguiente manera:

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

Esto no funciona (E2010 - tipos incompatibles) en D2006 hasta que cambie la definición de la constante a 'Puntos: TpointArray = ...' – yonojoy

+0

gracias @yonojoy - Pude haber estado usando una versión posterior en ese momento. También tuve un error de sintaxis con ',' en vez de ';' –

+1

Agregué un ejemplo de lo que es posible con XE7, espero que esté bien :-) –

4

Puede no porque no se puede expresar en el cuerpo del código es un punto en la forma en que puede expresarlo en la sección const.

Sin embargo, puede hacer algunos trucos para que su vida sea más fácil, especialmente si tiene una cantidad razonable de puntos.

se puede implementar un procedimiento simple como esto (código no probado):

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; 

... donde es TIntegerDynArray matriz dinámica de la RTL de números enteros. (De hecho, funcionará con cualquier matriz dinámica). Además, TPointArray en el ejemplo anterior también es dinámico.

Por lo tanto, con el fin de hacer su trabajo, puede hacerlo de esta manera:

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; 

A tener en cuenta:

  • Usted ve claramente cuáles son sus puntos
  • Usted puede ser muy productivo de esta manera
  • Puede usar BlendDimensions también en otras cosas no solo en esta
  • Puede expandir fácilmente BlendDimensions para 3 (o más) dimensiones
  • ... pero tenga cuidado porque se trata de una copia. :-) Con las PC de hoy, el punto débil será, por mucho, tu mano. :-) Te cansarás de escribir mucho más rápido hasta que el tiempo de copia se note.

HTH

+0

Me pregunto si este "constructor de matrices" se puede usar para "array of record" –

8

Plainth's answer muestra la sintaxis constructor como para matrices dinámicas. Puede utilizar ese directamente en una matriz TPoint para producir una función de ayuda mucho más simple:

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; 

Pero eso es una exageración. Delphi también le permite definir matrices abiertas en línea, y no hay una llamada de constructor adicional para escribir.El resultado utiliza su sintaxis propuesta original, pero con la matriz envuelta dentro de una llamada a función. Funcionará en todas las versiones de Delphi, mientras que la sintaxis "Crear" anterior es bastante nueva.

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; 

Es posible que desee considerar el uso de Gerry's answer acaba de dar a sus matrices de puntos nombres significativos, lo que podría ayudar al depurar y uno de los ocho números mágicos en esas definiciones de puntos es incorrecto.


Finalmente, una nota de lo Delphi significaba cuando dijo que "el [1, 2, 3, 4] sintaxis sólo puede trabajar para números enteros." Esa sintaxis define un conjunto de , no una matriz. No puede tener un conjunto de valores de registro, pero puede tener un conjunto de enteros. Un efecto secundario es que la sintaxis de un conjunto de enteros es la misma que la sintaxis de una matriz abierta de enteros. Creo que Delphi usa el contexto para descubrir a cuál te refieres, pero a veces puede adivinar lo contrario.

Cuestiones relacionadas