Значение параметра по умолчанию для TSomething в Delphi

#delphi #parameters #default-parameters

#delphi #параметры #по умолчанию-параметры

Вопрос:

Я хотел бы знать, возможно ли это в Delphi (или если есть чистый способ обойти это):

 type
 TSomething = record
  X, Y : Integer;
 end;
  

GetSomething( x, y ) -> Возвращает запись с этими значениями.

… и затем у вас есть эта функция с TSomething в качестве параметра, и вы хотите задать ее по умолчанию как

 function Foo( Something : TSomething = GetSomething( 1, 3 );
  

Здесь компилятор выдает ошибку, однако я не уверен, есть ли способ обойти это!

Можно ли это сделать?

Ответ №1:

Используйте перегрузку:

 procedure Foo(const ASomething: TSomething); overload;
begin
  // do something with ASomething
end;

procedure Foo; overload;
begin
  Foo(GetSomething(1, 3));
end;
  

Ответ №2:

Самый простой способ — использовать перегруженные процедуры:

 program TestOverloading;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TSomething = record
    X,Y : integer;
  end;

const
  cDefaultSomething : TSomething = (X:100; Y:200);

procedure Foo(aSomething : TSomething); overload;
begin
  writeln('X:',aSomething.X);
  writeln('Y:',aSomething.Y);
end;

procedure Foo; overload;
begin
  Foo(cDefaultSomething);
end;

begin
  Foo;
  readln;
end.
  

Ответ №3:

Используйте класс вместо записи, и что-то вроде этого сделало бы это:

 TSomething = class
public 
  X: integer;
  Y: integer
end;

procedure Foo(Something: TSomething = nil);
begin
  if (Something = nil) then
    Something := GetSomething(1, 3);
  ...
end;
  

Комментарии:

1. Чтобы исключить некоторые накладные расходы RTTI, X и Y могут быть объявлены как ‘public’ вместо неявного ‘published’

2. Спасибо @mjustin за указание на это. Мое неявное предположение состояло в том, что директиве для управления генерацией RTTI присвоено значение по умолчанию: {$M-} . 😉

Ответ №4:

Если вы используете указатель вместо типа записи, вы можете использовать nil в качестве значения по умолчанию:

 type
  TSomething = record
    X, Y : Integer;
  end;

  PSomething = ^TSomething;

function Foo(Something: PSomething = nil);
  

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