Обобщения в процедурах и функциях

 

Если абстрагироваться от типа данных, окажется, что логика очень многих алго­ритмов абсолютно одинакова. Например, алгоритм быстрой сортировки идентичен как для массива целых, так и для массива вещественных чисел. В подобных ситуа­циях благодаря созданию обобщенной функции (функции с параметром обобщен­ного типа) мы сможем определить смысл алгоритма, не отвлекаясь на обслужи­ваемый тип данных. Поэтому обобщенный тип данных может оказаться весьма полезным при разработке шаблонов процедурных типов данных, способных вос­принимать параметры любых типов.

По аналогии с объявлением обычной процедуры или функции, при создании шаб­лона процедуры или функции сначала указывают ключевое слово type, а затем имя типа. Сразу за именем следует синтаксический элемент, характерный для обобще­ний — пара угловых скобок <... > с названием обобщенного типа данных.

 

type тип_функции <имя_обобщенного_типа [,...]> =
function ( [параметр_обобщенного_типа [,...]]) : имя_обобщенного_типа; type тип_процедуры <шш_обобщенного_типа [,...]> =
procedure ([параметр_обобщенного_типа [,...]]

 

Листинг 3.2 демонстрирует порядок создания шаблона функции. В примере объяв­лена функция класса GetMaxValue () с двумя параметрами, тип которых не опреде­лен. Задачей функции является сравнение двух значений и возврат наибольшего из них.

 
 
uses System.SysUtils,System.Generics.Defaults;
type TGetMax = class
classfunction GetMaxValue<T>(X,Y: T):T;
end;
class function TGetMax.GetMaxValue<T>(X, Y: T): T;
var Comparer: IComparer<T>;
begin
{к сожалению, нельзя написать такой код: if X>Y thenResult:=X else Result:=Y; ведь мы не знаем тип данных сравниваемых параметров}
Comparer:=TComparer<T>.Default;
if Comparer.Compare(X,Y)>0 then Result:=X
else Result:=Y;
end;
var A:integer;
B:extended;
Ciansichar;
begin
A:=TGetMax.GetMaxValue<integer>(10,20);//сравниваем целые числа WriteLn(A);
B:=TGetMax.GetMaxValue<extended>(1/3,2/3);//вещественные числа WriteLn(В);
C:=TGetMax.GetMaxValUe<ansichar>(*Af,fBf);//сравниваемсимволы WriteLn(С); .
ReadLn;
end.
 

Реализация обобщенной функции требует ряда комментариев. К сожалению, срав­нивая данные неизвестного типа, мы не имеем возможности воспользоваться обыч­ными операторами сравнения (например: if x<y then ...). Вместо этого мы выну­ждены обратиться за услугами к интерфейсу icomparer (он описан в модуле System.Generics.Defaults). Этот интерфейс (кстати, также основанный на идее шаблонов) является профессионалом в области сравнения двух величин, для этого у него есть метод Compare (). Все остальное дело техники — в листинге 8.2 мы срав­нили значения трех различных типов данных.

������� ������ ��� dle ������� ��������� ������

Помоги проекту! Расскажи друзьям об этом сайте: