2010-02-20 6 views
16

Tôi hiện có điều này, và nó sucks:Delphi mảng khởi

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; 

nhưng thay vào đó, tôi muốn làm một cái gì đó như thế này:

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

Tuy nhiên, trên biên soạn, nó than phiền rằng cú pháp [1, 2, 3, 4] chỉ có thể làm việc cho Số nguyên.

Có cách nào để khởi tạo/khởi tạo một mảng Tpoint tương tự như cách tôi muốn không?

Trả lời

22

Mảng các bản ghi có thể được intialised trong các biểu thức 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; 

Trong XE7 nó có thể điền vào một mảng động của các hồ sơ như thế này:

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

Điều này không hoạt động (E2010 - loại không tương thích) trong D2006 cho đến khi tôi thay đổi định nghĩa của hằng số thành 'Điểm: TpointArray = ...' – yonojoy

+0

nhờ @yonojoy - Tôi có thể đang sử dụng phiên bản mới hơn vào lúc đó. Cũng có lỗi cú pháp với ',' thay vì ';' –

+1

Thêm một ví dụ về những gì có thể với XE7, hy vọng nó là ok :-) –

4

Bạn có thể không phải vì bạn không thể diễn tả bằng mã cơ thể một điểm trong cách mà bạn có thể thể hiện nó trong phần const.

Tuy nhiên bạn có thể thực hiện một số thủ thuật để giúp cuộc sống của bạn dễ dàng hơn, đặc biệt nếu bạn có số điểm hợp lý.

Bạn có thể thực hiện một thủ tục đơn giản như thế này (mã không kiểm tra):

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; 

... nơi TIntegerDynArray là mảng động của RTL của số nguyên. (Trong thực tế nó sẽ làm việc với bất kỳ mảng động nào). Ngoài ra, TPointArray trong ví dụ trên cũng là năng động.

Vì vậy, để làm tốt công việc của bạn, bạn có thể làm như thế này:

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; 

Những điều cần lưu ý:

  • Bạn thấy rõ ràng đó là điểm của bạn
  • Bạn có thể rất sản xuất theo cách này
  • Bạn cũng có thể sử dụng BlendDimensions cũng trên những thứ khác không chỉ trên số này
  • Bạn có thể dễ dàng mở rộng BlendDimensions cho 3 (hoặc nhiều hơn) kích thước
  • ... nhưng hãy cẩn thận vì một bản sao có liên quan. :-) Với máy tính ngày nay, điểm yếu sẽ là, cho đến nay, bàn tay của bạn. :-) Bạn sẽ cảm thấy mệt mỏi khi gõ nhanh hơn nhiều cho tới khi thời gian copy được chú ý.

HTH

+0

Tôi tự hỏi nếu điều này "mảng xây dựng" có thể được sử dụng cho "mảng hồ sơ" –

8

Plainth's answer chứng tỏ cú pháp constructor như cho mảng động. Bạn có thể sử dụng trực tiếp trên một mảng TPoint để mang lại chức năng trợ giúp đơn giản hơn nhiều:

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; 

Nhưng đó là quá mức cần thiết. Delphi cũng cho phép bạn xác định các mảng mở nội dòng và không có lệnh gọi hàm tạo bổ sung nào để ghi.Kết quả sử dụng cú pháp được đề xuất ban đầu của bạn, nhưng với mảng được bao bọc bên trong một cuộc gọi hàm. Nó sẽ làm việc trong tất cả các phiên bản Delphi, trong khi cú pháp "Tạo" ở trên là khá mới.

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; 

Bạn có thể muốn xem xét sử dụng Gerry's answer chỉ để cung cấp cho các mảng lại điểm tên có ý nghĩa, mà có thể giúp đỡ khi gỡ lỗi và một trong tám con số kỳ diệu trong những định nghĩa điểm là sai.


Cuối cùng, lưu ý về ý nghĩa của Delphi khi "cú pháp [1, 2, 3, 4] chỉ có thể hoạt động cho Số nguyên". Cú pháp đó xác định đặt, không phải là mảng. Bạn không thể có một bộ giá trị bản ghi, nhưng bạn có thể có một tập hợp các số nguyên. Một hiệu ứng phụ là cú pháp cho một tập hợp các số nguyên là giống như cú pháp cho một mảng mở của các số nguyên. Tôi nghĩ Delphi sử dụng ngữ cảnh để tìm ra ý bạn, nhưng đôi khi nó có thể đoán sai.