Подтвердить что ты не робот

Пропустить параметр записи без объявления его сначала как переменной

Если я пытаюсь вызвать процедуру, которая имеет тип записи (не объект) в качестве параметра, возможно ли каким-то образом передать данные этого параметра "inline", не указав сначала первую переменную этого типа?

Например, предположим, что у меня есть этот простой тип записи:

type TMyRecord = record
  AString: string;
  AnInt: Integer;
end;

и объявление этой процедуры:

procedure MyProcedure(Rec: TMyRecord);

Если я хочу вызвать MyProcedure, мне нужно объявить переменную типа TMyRecord или я могу сделать что-то вроде:

MyProcedure(TMyRecord("Test", 10));

Это не работает (XE2) (получите ошибку компилятора об ожидании ")" ).

Итак, могу ли я сделать что-то подобное? Или невозможно.

Спасибо

4b9b3361

Ответ 1

Возможно использование структуры advanced record.

Для получения дополнительной информации о advanced records см. раздел Записи (расширенный) в справке Delphi.

Это небольшой прототип, чтобы увидеть, как он работает в вашем случае, чтобы предварительно инициализировать запись в вызове функции/процедуры:

Type
  TRecord = record
   AString : String;
   AnInt : Integer;
   Constructor Create( Const s : String; i : Integer);
  end;

constructor TRecord.Create(const s: String; i: Integer);
begin
  AString := s;
  AnInt := i;
end;

procedure DoSomething( theRec : TRecord);
begin
  WriteLn(theRec.AString, ' ',theRec.AnInt);
end;

begin
  DoSomeThing( TRecord.Create('S',1));
  ReadLn;
end.

Глядя на RTF Delphi, см. определения типов записей TPoint и TRect в модуле system.types (XE2). Они определяют некоторые перегруженные конструкторы Create, которые используются во многих местах для предварительного инициализации структур записи в вызовах функций/процедур.

Ответ 2

Вопрос, который вы задаете, относится к читаемости кода, и есть решение, которое позволяет избежать необходимости создавать переменную. VCL использует это решение с записями TPoint и TRect.

Рассмотрим определение TPoint:

type
  TPoint = record
    X,Y integer
  end;

Чтобы передать TPoint в процедуру, которую вы можете выполнить:

var
  MyPoint : TPoint;

begin
  MyPoint.X := 5;
  MyPoint.Y := 7;
  DoSomething( MyPoint );
end;

Это нормально, но занимает 3 строки, когда также возможно использование функции factory Point:

begin
  DoSomething( Point(5,7) );
end;

В Delphi функция объявлена ​​следующим образом:

function Point( X, Y : integer ) : TPoint;
begin
  Result.X := X;
  Result.Y := Y;
end;

Затем вы можете вызвать эту функцию "inline", чтобы быстро создать запись "на лету" Вы увидите то же, что и для TRect и т.д. Я часто помещаю такую ​​функцию factory вместе с объявлением записи следующим образом, даже если я еще не планирую их использовать:

type
  TMyRecord = record
    A : integer;
    B : string;
  end;

function MyRecord( A : integer; const B : string ) : TMyRecord;
begin
  Result.A := A;
  Result.B := B;
end;

Использование этого метода может улучшить читаемость кода, а также гарантирует, что вы случайно не опустили установку элемента записи.

Ответ 3

Просто развлекайтесь с идеей Джона Легли:

type TRec = record
  X: string;
  Y: Integer;
end;

procedure TestRec(const Rec: array of const);
var
  R: TRec;

begin
  R.X:= string(Rec[0].VUnicodeString);
  R.Y:= Rec[1].VInteger;
  ShowMessage(R.X + IntToStr(R.Y));
end;

procedure TForm1.Button7Click(Sender: TObject);
begin
  TestRec(['Test', 22]);
end;

В качестве параметров array of const можно передать поля записей и назначить эти параметры локальной переменной записи.

Ответ 4

Было бы хорошо! Но, нет.

Если передача объектов inline действительно является вашей целью, возможно, вам понравятся параметры Open Array.

Procedure MyProcedure(const Vars: Array of Variant);
begin
  ShowMessage(VarToStr(Vars[0])+'  '+VarToStr(Vars[1]));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   MyProcedure(['Test', 12]);
end;

Вы также можете передать массив Const, который в основном представляет собой массив TVarRec, который является вариантом записи, который также включает информацию о типе как VType. Это забавный материал.

Отличную статью можно найти на углу Руди Дельфа: Rudy Delphi Corner, Параметры открытого массива