Difference between revisions of "Generics/pl"
(test) |
m (Fixed syntax highlighting) |
||
(One intermediate revision by one other user not shown) | |||
Line 1: | Line 1: | ||
− | + | {{Generics}} | |
+ | |||
+ | ==Wprowadzenie== | ||
+ | [[FPC]] ma oficjalne wsparcie dla typów generycznych w trybie [[Mode_ObjFPC|<syntaxhighlight lang="pascal" enclose="none">{$mode ObjFPC}</syntaxhighlight>]] począwszy od wersji 2.2. i w trybie [[Mode_Delphi|<syntaxhighlight lang="pascal" enclose="none">{$mode Delphi}</syntaxhighlight>]] począwszy od wersji 2.6.0. | ||
+ | |||
+ | Typy generyczne czasami są nazywane typami parametryzowanymi lub uogólnionymi. | ||
+ | |||
+ | FPC wspiera dwa różne dialekty, ponieważ typy generyczne zostały zaimplementowane w FPC kilka lat wcześniej niż w [[Delphi]]. | ||
+ | |||
+ | Możliwe jest używanie w [[Unit|module]] zapisów w składni <syntaxhighlight lang="pascal" enclose="none">{$mode ObjFPC}</syntaxhighlight> oraz innych modułów, które używają składnię <syntaxhighlight lang="pascal" enclose="none">{$mode Delphi}</syntaxhighlight>, i na odwrót. | ||
+ | |||
+ | Biblioteka '''Free Generics Library''' lub '''FGL''' jest zbiorem generycznych kolekcji zapisanych natywnie <syntaxhighlight lang="pascal" enclose="none">{$mode ObjFPC}</syntaxhighlight>. | ||
+ | |||
+ | Pakiet '''rtl-generics''' jest większym, i bardziej potężnym zbiorem pojemników generycznych zapisanych w <syntaxhighlight lang="pascal" enclose="none">{$mode Delphi}</syntaxhighlight> ponieważ stara się być kompatybilny z biblioteką generyczną Delphi. Ten pakiet jest dołączany standardowo do FPC 3.1.1.+ ale jest dosttępny już od wersji FPC 3.0.4. | ||
+ | |||
+ | Obydwie biblioteki '''FGL''' i '''rtl-generics''' mogą być użyte w obydwu trybach składniowych. | ||
+ | |||
+ | ==moduł fgl== | ||
+ | Najprostszym sposobem, aby zacząć pracę z typami generycznymi, jest użycie modułu FGL, który jest jednostką prototypową modułu opartego o [[Class | klasy]] generyczne. Jak dotąd zawiera on kilka podstawowych klas: | ||
+ | * TFPGList | ||
+ | * TFPGObjectList | ||
+ | * TFPGInterfacedObjectList | ||
+ | * TFPGMap | ||
+ | |||
+ | ===Rozpoczęcie=== | ||
+ | Poniższy prosty przykład pokazuje, w jaki sposób przechowywać wiele instancjie klasy zdefiniowanej przez użytkownika na liście: | ||
+ | |||
+ | <syntaxhighlight lang=pascal> | ||
+ | {$mode objfpc} | ||
+ | uses fgl; | ||
+ | |||
+ | type | ||
+ | TMyClass = class(TObject) | ||
+ | fld1 : string; | ||
+ | end; | ||
+ | |||
+ | TMyList = specialize TFPGObjectList<TMyClass>; | ||
+ | |||
+ | var | ||
+ | list : TMyList; | ||
+ | c : TMyClass; | ||
+ | |||
+ | begin | ||
+ | // utworzyć listę i dodać element | ||
+ | list := TMyList.Create; | ||
+ | c := TMyClass.Create; | ||
+ | c.fld1 := 'c1'; | ||
+ | list.Add(c); | ||
+ | // pobierz element z listy | ||
+ | c := list[0]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==Typowe klasy generyczne== | ||
+ | Jeśli typy generyczne zdefiniowane w jednostce FGL nie odpowiadają naszym potrzebom, to może trzeba definiować własne klasy rodzajowe od podstaw z wykorzystaniem podstawowych prymitywów językowych. | ||
+ | |||
+ | Ogólny klasa jest zdefiniowana za pomocą [[Słowo kluczowe | Hasło]] „” „generic” „” przed nazwą klasy i użyć w deklaracji klasy: | ||
+ | Klasa generyczna jest definiowana za pomocą słowa [[Słowo kluczowe | kluczowego]] '''generic''' przed nazwą klasy w deklaracji klasy: | ||
+ | <syntaxhighlight lang=pascal> | ||
+ | type | ||
+ | generic TList<T> = class | ||
+ | Items: array of T; | ||
+ | procedure Add(Value: T); | ||
+ | end; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Przykład utworzenia klasy generycznej: | ||
+ | |||
+ | <syntaxhighlight lang=pascal> | ||
+ | implementation | ||
+ | |||
+ | procedure TList.Add(Value: T); | ||
+ | begin | ||
+ | SetLength(Items, Length(Items) + 1); | ||
+ | Items[Length(Items) - 1] := Value; | ||
+ | end; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Klasa generyczna, [[Object|object]], [[Record|record]], [[Interface|interface]] i [[Method|method]] może być też wyspecjalizowana poprzez użycie słowa kluczowego '''specialize'''. | ||
+ | <syntaxhighlight lang=pascal> | ||
+ | Type | ||
+ | TIntegerList = specialize TList<Integer>; | ||
+ | TPointerList = specialize TList<Pointer>; | ||
+ | TStringList = specialize TList<string>; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Inne uwagi == | ||
+ | # [[Compiler|kompilator]] przetwarza pliki generyczne, ale zamiast generowania kodu przechowuje wszystkie znaki w buforze, wewnątrz pliku PPU. | ||
+ | # Kompilator analizuje typy specjalizacji; oraz ładuje bufor tokenów z pliku PPU i analizuje ponownie. Zastępuje typ generyczny parametrami (w większości przypadków "T") za pomocą określonego danego typu (na przykład '' '[[Longint | longint]]' '' '' '[[TObject]]' ''). Kod pojawia się w zasadzie tak, jakby ta sama klasa została napisana jako generyczna ale z T zastąpionym przez wybrany typu danych. | ||
+ | |||
+ | == Przykład == | ||
+ | {{:Jak używać typów generycznych}} | ||
+ | |||
+ | ==Zobacz także== | ||
+ | * [[Templates]] | ||
+ | * [[Generics proposals]] | ||
+ | * [[Data Structures, Containers, Collections]] | ||
+ | |||
+ | ==Linki zewnętrzne== |
Revision as of 12:05, 16 February 2020
│
English (en) │
français (fr) │
한국어 (ko) │
polski (pl) │
русский (ru) │
Wprowadzenie
FPC ma oficjalne wsparcie dla typów generycznych w trybie {$mode ObjFPC}
począwszy od wersji 2.2. i w trybie {$mode Delphi}
począwszy od wersji 2.6.0.
Typy generyczne czasami są nazywane typami parametryzowanymi lub uogólnionymi.
FPC wspiera dwa różne dialekty, ponieważ typy generyczne zostały zaimplementowane w FPC kilka lat wcześniej niż w Delphi.
Możliwe jest używanie w module zapisów w składni {$mode ObjFPC}
oraz innych modułów, które używają składnię {$mode Delphi}
, i na odwrót.
Biblioteka Free Generics Library lub FGL jest zbiorem generycznych kolekcji zapisanych natywnie {$mode ObjFPC}
.
Pakiet rtl-generics jest większym, i bardziej potężnym zbiorem pojemników generycznych zapisanych w {$mode Delphi}
ponieważ stara się być kompatybilny z biblioteką generyczną Delphi. Ten pakiet jest dołączany standardowo do FPC 3.1.1.+ ale jest dosttępny już od wersji FPC 3.0.4.
Obydwie biblioteki FGL i rtl-generics mogą być użyte w obydwu trybach składniowych.
moduł fgl
Najprostszym sposobem, aby zacząć pracę z typami generycznymi, jest użycie modułu FGL, który jest jednostką prototypową modułu opartego o klasy generyczne. Jak dotąd zawiera on kilka podstawowych klas:
- TFPGList
- TFPGObjectList
- TFPGInterfacedObjectList
- TFPGMap
Rozpoczęcie
Poniższy prosty przykład pokazuje, w jaki sposób przechowywać wiele instancjie klasy zdefiniowanej przez użytkownika na liście:
{$mode objfpc}
uses fgl;
type
TMyClass = class(TObject)
fld1 : string;
end;
TMyList = specialize TFPGObjectList<TMyClass>;
var
list : TMyList;
c : TMyClass;
begin
// utworzyć listę i dodać element
list := TMyList.Create;
c := TMyClass.Create;
c.fld1 := 'c1';
list.Add(c);
// pobierz element z listy
c := list[0];
Typowe klasy generyczne
Jeśli typy generyczne zdefiniowane w jednostce FGL nie odpowiadają naszym potrzebom, to może trzeba definiować własne klasy rodzajowe od podstaw z wykorzystaniem podstawowych prymitywów językowych.
Ogólny klasa jest zdefiniowana za pomocą Hasło „” „generic” „” przed nazwą klasy i użyć w deklaracji klasy: Klasa generyczna jest definiowana za pomocą słowa kluczowego generic przed nazwą klasy w deklaracji klasy:
type
generic TList<T> = class
Items: array of T;
procedure Add(Value: T);
end;
Przykład utworzenia klasy generycznej:
implementation
procedure TList.Add(Value: T);
begin
SetLength(Items, Length(Items) + 1);
Items[Length(Items) - 1] := Value;
end;
Klasa generyczna, object, record, interface i method może być też wyspecjalizowana poprzez użycie słowa kluczowego specialize.
Type
TIntegerList = specialize TList<Integer>;
TPointerList = specialize TList<Pointer>;
TStringList = specialize TList<string>;
Inne uwagi
- kompilator przetwarza pliki generyczne, ale zamiast generowania kodu przechowuje wszystkie znaki w buforze, wewnątrz pliku PPU.
- Kompilator analizuje typy specjalizacji; oraz ładuje bufor tokenów z pliku PPU i analizuje ponownie. Zastępuje typ generyczny parametrami (w większości przypadków "T") za pomocą określonego danego typu (na przykład ' longint' 'TObject' ). Kod pojawia się w zasadzie tak, jakby ta sama klasa została napisana jako generyczna ale z T zastąpionym przez wybrany typu danych.