Ce face extension type
extension type IdClient(int valoare) {} creează un tip separat pentru analizor: un IdClient nu se poate folosi unde se cere un int sau un IdProdus, deci nu le mai poți încurca. La rulare însă nu există niciun obiect nou: valoarea este exact int-ul dinăuntru, fără memorie sau timp în plus.
Membrii tipului reprezentat nu sunt disponibili automat. Adaugi doar metodele pe care le vrei, sau scrii implements int ca să-i păstrezi pe toți. Valoarea interioară se citește prin numele dat în paranteze (id.valoare).
Pentru că la rulare tipul „dispare”, is și as se uită la tipul reprezentat: IdClient(5) is int este true. Extension types sunt folosite mult pentru interoperabilitatea cu JavaScript (dart:js_interop).
Exemple
Exemplul 1: Identificatori care nu se pot încurca
Ambele tipuri sunt int la rulare, dar afiseazaClient(IdProdus(7)) nu ar trece de analizor. runtimeType arată că la rulare valoarea este un simplu int.
extension type IdClient(int valoare) {}
extension type IdProdus(int valoare) {}
void afiseazaClient(IdClient id) => print('Clientul #${id.valoare}');
void main() {
final client = IdClient(1024);
final produs = IdProdus(7);
afiseazaClient(client);
print('Produsul #${produs.valoare}');
print(client.runtimeType);
}
Rezultat
Clientul #1024
Produsul #7
int
Exemplul 2: Sume de bani cu operații proprii
Bani are doar operațiile alese; implements nu este folosit, deci Bani nu are restul metodelor lui int.
extension type Bani(int bani) {
Bani.lei(double lei) : bani = (lei * 100).round();
Bani operator +(Bani alta) => Bani(bani + alta.bani);
String get afisare => '${(bani / 100).toStringAsFixed(2)} lei';
}
void main() {
final total = Bani.lei(19.99) + Bani.lei(5.5) + Bani(1);
print(total.afisare);
print(total.bani);
}
Rezultat
25.50 lei
2550
Exemplul 3: implements: păstrarea membrilor tipului de bază
Cu implements int, Varsta poate fi folosită ca un int, dar are și getter-ul propriu.
extension type Varsta(int ani) implements int {
bool get esteMajor => ani >= 18;
}
void main() {
final v = Varsta(17);
print(v.esteMajor);
print(v + 1);
int numar = v;
print(numar.isOdd);
}
Rezultat
false
18
true
Greșeli frecvente
- Să folosești extension types pentru siguranță la rulare:
(x as Object) is IdClientestetruepentru oriceint, pentru că tipul nu mai există la rulare. - Atribuirea unui extension type unei variabile de tipul reprezentat fără
implements:A value of type 'Bani' can't be assigned to a variable of type 'int'. - Să-l confunzi cu
extension:extensionadaugă metode tipului existent,extension typecreează un tip nou.
Comenzi înrudite
extension: Adaugă metode, getter-e și operatori unui tip existent (chiar și String sau int), fără să-l modifici.typedef: Dă un nume (alias) unui tip, de obicei unui tip de funcție sau unui tip generic lung.class: Definește un tip nou de obiect, cu câmpuri (date) și metode (comportament).external: Declară o funcție sau un câmp al cărui corp este scris în altă parte: în C (dart:ffi), JavaScript sau în SDK.