Generics/pl
│
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.