Sign in Join
Wiki copytemporary

Generics/ru: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Вступление
22
3-[[FPC]] имеет официальную поддержку дженериков(обобщений) в синтаксисе [[Mode ObjFPC|{$mode ObjFPC}]], начиная с версии 2.2, и [[Mode Delphi|{$mode Delphi}]] синтаксис начиная с версии 2.6.0.\
4-Дженерики иногда называют параметризованными типами.\
5-Причина, по которой FPC поддерживает два разных диалекта, Objfpc и Delphi, заключается в том, что у FPC были дженерики до Delphi. Можно использовать модули, написанные в синтаксисе Objfpc, в других модулях, использующих синтаксис Delphi, и наоборот.
3+[[FPC]] имеет официальную поддержку дженериков(обобщений) в синтаксисе [[Mode ObjFPC|`{$mode ObjFPC}`]], начиная с версии 2.2, и [[Mode Delphi|`{$mode Delphi}`]] синтаксис начиная с версии 2.6.0.
4+Дженерики иногда называют параметризованными типами.
5+Причина, по которой FPC поддерживает два разных диалекта, Objfpc и Delphi, заключается в том, что у FPC были дженерики до Delphi. Можно использовать модули, написанные в синтаксисе Objfpc, в других модулях, использующих синтаксис Delphi, и наоборот.
66
7-**Free Generics Library** или **FGL** является нативной реализацией [[Templates|class templates]], написанной в обобщенном синтаксисе Objfpc.\
8-**Rtl-generics package** является реализацией [[Templates|class templates]], написанной в синтаксисе дженериков Delphi, и пытается быть совместимым с библиотекой дженериков Delphi. Этот пакет является стандартным в FPC 3.1.1.+, но есть версия, доступная для FPC 3.0.4.\
9-Обе \[библиотеки\], **FGL** и rtl-generics могут использоваться в обоих режимах.
7+**Free Generics Library** или **FGL** является нативной реализацией [[Templates|class templates]], написанной в обобщенном синтаксисе Objfpc.
8+**Rtl-generics package** является реализацией [[Templates|class templates]], написанной в синтаксисе дженериков Delphi, и пытается быть совместимым с библиотекой дженериков Delphi. Этот пакет является стандартным в FPC 3.1.1.+, но есть версия, доступная для FPC 3.0.4.
9+Обе [библиотеки], **FGL** и rtl-generics могут использоваться в обоих режимах.
1010
1111## Модуль fgl
1212
13-Самый простой способ начать работу с дженериками - это использовать [fgl unit](http://freepascal.org/docs-html/current/rtl/fgl/index.html), который является модулем-прототипом для классов дженериков базовой системы. Пока он содержит несколько основных классов:
13+Самый простой способ начать работу с дженериками - это использовать [fgl unit](<http://freepascal.org/docs-html/current/rtl/fgl/index.html>), который является модулем-прототипом для классов дженериков базовой системы. Пока он содержит несколько основных классов:
1414
15-- TFPGList
16-- TFPGObjectList
17-- TFPGInterfacedObjectList
18-- TFPGMap
15+ * TFPGList
16+ * TFPGObjectList
17+ * TFPGInterfacedObjectList
18+ * TFPGMap
1919
2020### Как начать
2121
22-В следующем простом примере показано, как хранить несколько экземпляров определенного пользователем класса в списке:
23-
24-``` pascal
22+В следующем простом примере показано, как хранить несколько экземпляров определенного пользователем класса в списке:
23+```
2524{$mode objfpc}
26-uses fgl;
27-
28-type
29- TMyClass = class(TObject)
30- fld1 : string;
31- end;
32-
33- TMyList = specialize TFPGObjectList<TMyClass>;
34-
35-var
36- list : TMyList;
37- c : TMyClass;
38-
39-begin
40- // создаем список и добавляем элемент
41- list := TMyList.Create;
42- c := TMyClass.Create;
43- c.fld1 := 'c1';
44- list.Add(c);
45- // получаем элемент из списка
46- c := list[0];
25+ uses fgl;
26+
27+ type
28+ TMyClass = class(TObject)
29+ fld1 : string;
30+ end;
31+
32+ TMyList = specialize TFPGObjectList<TMyClass>;
33+
34+ var
35+ list : TMyList;
36+ c : TMyClass;
37+
38+ begin
39+ // создаем список и добавляем элемент
40+ list := TMyList.Create;
41+ c := TMyClass.Create;
42+ c.fld1 := 'c1';
43+ list.Add(c);
44+ // получаем элемент из списка
45+ c := list[0];
4746```
4847
4948## Пользовательские классы дженериков
5049
51-Если дженерики, определенные в модуле fgl, не соответствуют вашим потребностям, вам может потребоваться определить свои собственные классы дженериков с нуля, используя базовые языковые примитивы.
52-
53-Класс-дженерик определяется с помощью [[keyword]] (ключевого слова) **generic** перед именем класса и используется в объявлении класса:
50+Если дженерики, определенные в модуле fgl, не соответствуют вашим потребностям, вам может потребоваться определить свои собственные классы дженериков с нуля, используя базовые языковые примитивы.
5451
55-``` pascal
52+Класс-дженерик определяется с помощью [[keyword]] (ключевого слова) **generic** перед именем класса и используется в объявлении класса:
53+```
5654type
57- generic TList<T> = class
58- Items: array of T;
59- procedure Add(Value: T);
60- end;
55+ generic TList<T> = class
56+ Items: array of T;
57+ procedure Add(Value: T);
58+ end;
6159```
6260
63-Пример реализации класса-дженерика:
64-
65-``` pascal
61+Пример реализации класса-дженерика:
62+```
6663implementation
67-
68-procedure TList.Add(Value: T);
69-begin
70- SetLength(Items, Length(Items) + 1);
71- Items[Length(Items) - 1] := Value;
72-end;
64+
65+ procedure TList.Add(Value: T);
66+ begin
67+ SetLength(Items, Length(Items) + 1);
68+ Items[Length(Items) - 1] := Value;
69+ end;
7370```
7471
75-Класс-дженерик может быть просто специализирован для определенного типа с помощью ключевого слова **specialize**.
76-
77-``` pascal
72+Класс-дженерик может быть просто специализирован для определенного типа с помощью ключевого слова **specialize**.
73+```
7874Type
79- TIntegerList = specialize TList<Integer>;
80- TPointerList = specialize TList<Pointer>;
81- TStringList = specialize TList<string>;
75+ TIntegerList = specialize TList<Integer>;
76+ TPointerList = specialize TList<Pointer>;
77+ TStringList = specialize TList<string>;
8278```
8379
8480## Другие пункты
8581
86-1. Компилятор анализирует общий тип, но вместо генерации кода он сохраняет все токены в буфере токенов внутри файла PPU.
87-2. Компилятор разбирает специализацию; для этого он загружает буфер токенов из файла PPU и анализирует его снова. Он заменяет общие параметры (в большинстве примеров "T") конкретным заданным типом (например, **LongInt**, **TObject**).
82+ 1. Компилятор анализирует общий тип, но вместо генерации кода он сохраняет все токены в буфере токенов внутри файла PPU.
83+ 2. Компилятор разбирает специализацию; для этого он загружает буфер токенов из файла PPU и анализирует его снова. Он заменяет общие параметры (в большинстве примеров "T") конкретным заданным типом (например, **LongInt** , **TObject**).
8884
89-Код в основном выглядит так, как будто тот же класс был написан как общий, но с заменой T на данный тип.
85+Код в основном выглядит так, как будто тот же класс был написан как общий, но с заменой T на данный тип.
9086
91-Поэтому в теории не должно быть различий в скорости между «нормальным» классом и классом-дженериком.
87+Поэтому в теории не должно быть различий в скорости между «нормальным» классом и классом-дженериком.
9288
9389## Примеры
9490
95-Пример использования дженериков для написания функции gmax(), которая принимает максимум две еще-не-типизированные переменные. Обратите внимание, что функции имеют пространство имен по имени класса. Недостатком может быть то, что дженерики не могут быть перегружены.
96-
97-``` pascal
91+Пример использования дженериков для написания функции gmax(), которая принимает максимум две еще-не-типизированные переменные. Обратите внимание, что функции имеют пространство имен по имени класса. Недостатком может быть то, что дженерики не могут быть перегружены.
92+```
9893program UseGenerics;
99-
100-{$mode objfpc}{$H+}
101-
102-type
103- generic TFakeClass<_GT> = class
104- class function gmax(a,b: _GT):_GT;
105- end;
106-
107- TFakeClassInt = specialize TFakeClass<integer>;
108- TFakeClassDouble = specialize TFakeClass<double>;
109-
110- class function TFakeClass.gmax(a,b: _GT):_GT;
111- begin
112- if a > b then
113- result := a
114- else
115- result := b;
116- end;
117-
118-begin
119- // показать большее из двух целых [чисел]
120- writeln( 'Integer GMax:', TFakeClassInt.gmax( 23, 56 ) );
121- // показать большее из двух [чисел] с плавающей точкой
122- writeln( 'Double GMax:', TFakeClassDouble.gmax( 23.89, 56.5) );
123- readln();
124-end.
94+
95+ {$mode objfpc}{$H+}
96+
97+ type
98+ generic TFakeClass<_GT> = class
99+ class function gmax(a,b: _GT):_GT;
100+ end;
101+
102+ TFakeClassInt = specialize TFakeClass<integer>;
103+ TFakeClassDouble = specialize TFakeClass<double>;
104+
105+ class function TFakeClass.gmax(a,b: _GT):_GT;
106+ begin
107+ if a > b then
108+ result := a
109+ else
110+ result := b;
111+ end;
112+
113+ begin
114+ // показать большее из двух целых [чисел]
115+ writeln( 'Integer GMax:', TFakeClassInt.gmax( 23, 56 ) );
116+ // показать большее из двух [чисел] с плавающей точкой
117+ writeln( 'Double GMax:', TFakeClassDouble.gmax( 23.89, 56.5) );
118+ readln();
119+ end.
125120```
126121
127122## См. также
128123
129-- [[Templates/ru|Templates]]
130-- [[Generics proposals]]
131-- [[Data Structures, Containers, Collections]]
124+ * [[Templates/ru|Templates]]
125+ * [[Generics proposals]]
126+ * [[Data Structures, Containers, Collections]]
132127
133128## Внешние ссылки
134129
135-- [Free Pascal: Reference guide - Generics](http://www.freepascal.org/docs-html/ref/refch8.html)
136-- [Используем дженерики в Delphi!](http://keeper89.blogspot.com/2011/07/delphi-1.html)
137-- [Использование стандартных дженериков Delphi для работы с наборами данных](http://proghouse.ru/programming/49-delphi-generics)
130+ * [Free Pascal: Reference guide - Generics](<http://www.freepascal.org/docs-html/ref/refch8.html>)
131+ * [Используем дженерики в Delphi!](<https://habr.com/ru/articles/314780/>)
132+ * [Использование стандартных дженериков Delphi для работы с наборами данных](<http://proghouse.ru/programming/49-delphi-generics>)
138133
139134---
140-*From the Free Pascal wiki, page "Generics/ru", as it stood on 2022-08-06 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
135+*From the Free Pascal wiki, page "Generics/ru", as the Internet Archive kept it on 2025-04-18, last changed on 2024-09-11. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history