15
15
16
16
## How it works
17
17
18
- In general :
18
+ In a nutshell :
19
19
+ parse generics classes;
20
- + generate concrete classes based on them;
20
+ + generate concrete classes based on them (you can choose ` monomorphization ` or ` type-erasure ` ) ;
21
21
+ autoload concrete classes instead of generics classes.
22
22
23
23
For example, you need to add several PHP files:
@@ -134,26 +134,55 @@ composer.json
134
134
135
135
A new class is generated for each generic argument combination.
136
136
137
- ![ ] ( ./doc/monomorphization.png )
137
+ Before ` monomorphization ` :
138
+ ``` php
139
+ <?php
138
140
139
- ### Command
140
- ``` bash
141
- composer dump-generics
141
+ namespace App;
142
+
143
+ class Box<T > {
144
+
145
+ private ?T $data = null;
146
+
147
+ public function set(T $data): void
148
+ {
149
+ $this->data = $data;
150
+ }
151
+
152
+ public function get(): ?T
153
+ {
154
+ return $this->data;
155
+ }
156
+ }
142
157
```
143
158
144
- ### Where in class can generics be used?
159
+ After ` monomorphization ` :
160
+ ``` php
161
+ <?php
162
+
163
+ namespace App;
145
164
146
- + extends
147
- + implements
148
- + trait use
149
- + property type
150
- + method argument type
151
- + method return type
152
- + instanceof
153
- + new
154
- + class constants
165
+ class BoxForInt {
155
166
156
- An example of class that uses generics:
167
+ private ?int $data = null;
168
+
169
+ public function set(int $data) : void
170
+ {
171
+ $this->data = $data;
172
+ }
173
+
174
+ public function get() : ?int
175
+ {
176
+ return $this->data;
177
+ }
178
+ }
179
+ ```
180
+ #### Command
181
+ ``` bash
182
+ composer dump-generics
183
+ ```
184
+
185
+ #### Where in class can generics be used?
157
186
``` php
158
187
<?php
159
188
@@ -163,66 +192,49 @@ use App\Entity\Cat;
163
192
use App\Entity\Bird;
164
193
use App\Entity\Dog;
165
194
166
- class Test extends GenericClass<Cat > implements GenericInterface<Bird > {
195
+ class Test extends GenericClass<Cat > implements GenericInterface<Bird > { // < -- extends / implements
167
196
168
- use GenericTrait<Dog >;
197
+ use GenericTrait <Dog >; // < -- trait use
169
198
170
- private GenericClass<int >|GenericClass<Dog > $var;
199
+ private GenericClass <int >|GenericClass<Dog > $var; // < -- property type
171
200
172
- public function test(GenericInterface<int >|GenericInterface<Dog > $var): GenericClass<string >|GenericClass<Bird > {
173
-
174
- var_dump($var instanceof GenericInterface<int >);
201
+ public function test(GenericInterface <int >|GenericInterface<Dog > $var): GenericClass<string >|GenericClass<Bird > { // <-- method argument /return type
175
202
176
- var_dump(GenericClass <int >::class);
203
+ var_dump($var instanceof GenericInterface <int >); // < -- instanceof
177
204
178
- var_dump(GenericClass<array >::CONSTANT);
205
+ var_dump(GenericClass <int >::class); // <-- class constants
206
+ var_dump(GenericClass <array >::CONSTANT); // <-- class constants
179
207
180
- return new GenericClass<float >();
208
+ return new GenericClass <float >(); // < -- new
181
209
}
182
210
}
183
211
```
184
212
185
- ### Where in generic class can parameters be used?
186
-
187
- + extends
188
- + implements
189
- + trait use
190
- + property type
191
- + method argument type
192
- + method return type
193
- + instanceof
194
- + new
195
- + class constants
196
-
197
- And example of generic class:
213
+ #### Where in generic class can parameters be used?
198
214
```php
199
215
<?php
200
216
201
217
namespace App;
202
218
203
- class Test<T ,V > extends GenericClass<T > implements GenericInterface<V > {
219
+ class Test <T,V > extends GenericClass<T > implements GenericInterface<V > { // < -- extends / implements
204
220
205
- use GenericTrait<T >;
206
- use T;
221
+ use GenericTrait <T >; // < -- trait use
222
+ use T; // < -- trait use
207
223
208
- private T|GenericClass<V > $var;
224
+ private T|GenericClass <V > $var; // < -- property type
209
225
210
- public function test(T|GenericInterface<V > $var): T|GenericClass<V > {
211
-
212
- var_dump($var instanceof GenericInterface<V >);
226
+ public function test(T|GenericInterface <V > $var): T|GenericClass<V > { // <-- method argument /return type
213
227
214
- var_dump($var instanceof T);
228
+ var_dump($var instanceof GenericInterface <V >); // <-- instanceof
229
+ var_dump($var instanceof T); // <-- instanceof
215
230
216
- var_dump(GenericClass<T >::class);
231
+ var_dump(GenericClass <T >::class); // <-- class constants
232
+ var_dump(T::class); // <-- class constants
233
+ var_dump(GenericClass <T >::CONSTANT); // <-- class constants
234
+ var_dump(T::CONSTANT); // <-- class constants
217
235
218
- var_dump(T::class);
219
-
220
- var_dump(GenericClass<T >::CONSTANT);
221
-
222
- var_dump(T::CONSTANT);
223
-
224
- $obj1 = new T();
225
- $obj2 = new GenericClass<V >();
236
+ $obj1 = new T(); // <-- new
237
+ $obj2 = new GenericClass <V >(); // <-- new
226
238
227
239
return $obj2;
228
240
}
@@ -235,26 +247,56 @@ class Test<T,V> extends GenericClass<T> implements GenericInterface<V> {
235
247
236
248
A new class is generated without generics arguments.
237
249
238
- ![ ] ( ./doc/type-erasure.png )
250
+ Before `type erasure`:
251
+ ```php
252
+ <?php
253
+
254
+ namespace App;
239
255
240
- ### Command
241
- ``` bash
242
- composer dump-generics --type=type-erasure
256
+ class Box <T > {
257
+
258
+ private ?T $data = null;
259
+
260
+ public function set(T $data): void
261
+ {
262
+ $this->data = $data;
263
+ }
264
+
265
+ public function get(): ?T
266
+ {
267
+ return $this->data;
268
+ }
269
+ }
243
270
```
244
271
245
- ### Where in class can generics be used?
272
+ After ` type erasure ` :
273
+ ``` php
274
+ <?php
275
+
276
+ namespace App;
246
277
247
- + extends
248
- + implements
249
- + trait use
250
- + property type
251
- + method argument type
252
- + method return type
253
- + instanceof
254
- + new
255
- + class constants
278
+ class Box {
256
279
257
- An example of class that uses generics:
280
+ private $data = null;
281
+
282
+ public function set($data) : void
283
+ {
284
+ $this->data = $data;
285
+ }
286
+
287
+ public function get()
288
+ {
289
+ return $this->data;
290
+ }
291
+ }
292
+ ```
293
+
294
+ #### Command
295
+ ``` bash
296
+ composer dump-generics --type=type-erasure
297
+ ```
298
+
299
+ #### Where in class can generics be used?
258
300
``` php
259
301
<?php
260
302
@@ -264,62 +306,50 @@ use App\Entity\Cat;
264
306
use App\Entity\Bird;
265
307
use App\Entity\Dog;
266
308
267
- class Test extends GenericClass<Cat > implements GenericInterface<Bird > {
309
+ class Test extends GenericClass<Cat > implements GenericInterface<Bird > { // < -- extends / implements
268
310
269
- use GenericTrait<Dog >;
311
+ use GenericTrait <Dog >; // < -- trait use
270
312
271
- private GenericClass<int >|GenericClass<Dog > $var;
313
+ private GenericClass <int >|GenericClass<Dog > $var; // < -- property type
272
314
273
- public function test(GenericInterface<int >|GenericInterface<Dog > $var): GenericClass<string >|GenericClass<Bird > {
315
+ public function test(GenericInterface <int >|GenericInterface<Dog > $var): GenericClass<string >|GenericClass<Bird > { // < -- method argument / return type
274
316
275
- var_dump($var instanceof GenericInterface<int >);
317
+ var_dump($var instanceof GenericInterface <int >); // < -- instanceof
276
318
277
- var_dump(GenericClass<int >::class);
319
+ var_dump(GenericClass <int >::class); // <-- class constants
320
+ var_dump(GenericClass <array >::CONSTANT); // <-- class constants
278
321
279
- var_dump(GenericClass<array >::CONSTANT);
280
-
281
- return new GenericClass<float >();
322
+ return new GenericClass <float >(); // <-- new
282
323
}
283
324
}
284
325
```
285
326
286
- :blue_book : You can read more about ` type-erasure ` [ here] ( https://dev.to/mrsuh/generics-implementation-approaches-3bf0 ) .
287
-
288
- ### Where in generic class can parameters be used?
289
-
290
- + extends
291
- + implements
292
- + property type
293
- + method argument type
294
- + method return type
295
-
296
- And example of generic class:
327
+ #### Where in generic class can parameters be used?
297
328
```php
298
329
<?php
299
330
300
331
namespace App;
301
332
302
- class Test<T ,V > extends GenericClass<T > implements GenericInterface<V > {
333
+ class Test <T,V > extends GenericClass<T > implements GenericInterface<V > { // < -- extends / implements
303
334
304
- use GenericTrait<T >;
335
+ use GenericTrait <T >; // < -- trait use
305
336
306
- private GenericClass<V > $var;
337
+ private GenericClass <V > $var; // < -- property type
307
338
308
- public function test(T|GenericInterface<V > $var): T|GenericClass<V > {
339
+ public function test(T|GenericInterface <V > $var): T|GenericClass<V > { // < -- method argument / return type
309
340
310
- var_dump($var instanceof GenericInterface<V >);
341
+ var_dump($var instanceof GenericInterface <V >); // < -- instanceof
311
342
312
- var_dump(GenericClass<T >::class);
343
+ var_dump(GenericClass <T >::class); // <-- class constants
344
+ var_dump(GenericClass <T >::CONSTANT); // <-- class constants
313
345
314
- var_dump(GenericClass<T >::CONSTANT);
315
-
316
- $obj2 = new GenericClass<V >();
317
-
318
- return $obj2;
346
+ return new GenericClass <V >(); // <-- new
319
347
}
320
348
}
321
349
```
322
350
351
+ :blue_book: You can read more about `type-erasure` [here](https: //dev.to /mrsuh /generics-implementation-approaches-3bf0).
352
+
323
353
## Features
324
354
325
355
#### What syntax is used?
0 commit comments