У меня в настоящее время есть это, и это сосет:
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, подобного способу, которым я хочу?
Ответ 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, в то время как синтаксис «Создать» выше довольно новый.
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;
Возможно, вы захотите использовать ответ Джерри только для того, чтобы дать вашим массивам точек значимые имена, которые могут помочь при отладке, и одно из восьми магических чисел в этих определениях точек неверно.
Наконец, примечание о том, что имел в виду Delphi, когда говорил: «синтаксис [1, 2, 3, 4] может работать только для целых чисел». Этот синтаксис определяет набор , а не массив. У вас не может быть набора значений записей, но вы можете иметь набор целых чисел. Побочным эффектом является то, что синтаксис набора целых чисел такой же, как синтаксис открытого массива целых чисел. Я думаю, что Delphi использует контекст, чтобы выяснить, какой из них вы имеете в виду, но иногда он может угадывать неверно.
Массивы записей можно инциализировать в выражениях 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;
Вы не можете, потому что вы не можете выразить в теле кода точку так, как вы можете выразить ее в разделе 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 (или более) измерения HTH