-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathenumerations.xml
More file actions
1023 lines (878 loc) · 28 KB
/
enumerations.xml
File metadata and controls
1023 lines (878 loc) · 28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 83e2056f071742c44d2b0bdbc8574d73697c7a08 Maintainer: nilgun Status: ready -->
<chapter xml:id="language.enumerations" xmlns="http://docbook.org/ns/docbook">
<title>Sayılamalar</title>
<sect1 xml:id="language.enumerations.overview">
<title>Sayılamalara giriş</title>
<?phpdoc print-version-for="enumerations"?>
<para>
Sayılamalar (veya tür adı olarak "enum") tanımlamalarda, olası
değer kümelerinden biriyle sınırlanabilen özel bir veri türünü
kullanabilmeyi sağlar. Bu, "geçersiz durumların devre dışı bırakılmasını"
sağladığından, bir etki alanı modeli tanımlarken özellikle yararlı
olabilir.
</para>
<para>
Sayılamalar çoğu yazılım dilinde çok çeşitli farklı özelliklerle
yer almaktadır. PHP'de ise, <literal>enum</literal> özel bir nesne
çeşididir. Kendisi bir sınıf olup içeriği kılıflar (case) bu sınıfın tekil
olarak örneklenmiş nesneleridir. Yani, bir sayılama kılıfı (enum
case) geçerli bir nesne olup, tür sınamaları dahil, bir nesnenin
kullanılabildiği her yerde kullanılabilir.
</para>
<para>
Sayılamaların en bilinen örneği, &true; ve &false; değerlerini
(ikil) sayılı tür olarak içeren yerleşik mantıksal türdür.
Sayılamalar geliştiricinin kendi keyfi sayılamalarını
tanımlayabilmesini sağlar.
</para>
</sect1>
<sect1 xml:id="language.enumerations.basics">
<title>Temel Sayılamalar</title>
<para>
Sayılamalar sınıflara benzer ve sınıflar, arayüzler ve niteliklerle
aynı isim alanını paylaşır. Ayrıca, aynı yolla otomatik yüklenebilir. Her
sayılama, sınırlı ve sabit sayıda olası değer içeren yeni bir tür
tanımlar.
</para>
<programlisting role="php">
<![CDATA[
<?php
enum Deste
{
case Kupalar;
case Karolar;
case Sinekler;
case Maçalar;
}
?>
]]>
</programlisting>
<para>
Bu bildirim <literal>Deste</literal> adında yalnız ve yalnız dört meşru
değer içeren yeni bir sayılama türü oluşturur:
<literal>Deste::Kupalar</literal>, <literal>Deste::Karolar</literal>,
<literal>Deste::Sinekler</literal> ve <literal>Deste::Maçalar</literal>.
Değişkenlere bu dört değerden biri atanabilir. Yalnızca sayılama
türünde değerlerin aktarılabileceği bir işlevin türü sadece o
sayılama türüne karşı tür denetimine tabi tutulabilir.
</para>
<programlisting role="php">
<![CDATA[
<?php
function kart_seç(Deste $deste)
{
/* ... */
}
$val = Deste::Karolar;
// OK
kart_seç($val);
// OK
kart_seç(Deste::Sinekler);
// Tür hatası: kart_seç(): Bağımsız değişken #1 ($deste) Deste türünde olmalıyken string türünde
kart_seç('Sinekler');
?>
]]>
</programlisting>
<para>
Bir sayılama sıfır veya daha fazla sayıda <literal>case</literal>
tanımı içerebilir ve azami bir sınır yoktur. <literal>case</literal>
içermeyen sayılamalar sözdizimsel olarak geçerli olsa da
yararsızdır.
</para>
<para>
Sayılama kılıflarında PHP'nın yaftalara uyguladığı sözdizimi
kuralları uygulanır, daha fazla bilgi
<link linkend="language.constants">Sabitler</link> bölümünde bulunabilir.
</para>
<para>
Öntanımlı olarak, bir <literal>case</literal> özünde bir sayıl değerle
desteklenmez. Yani, <literal>Deste::Kupalar</literal> sayıl olarak
<literal>"0"</literal> değerine eşit değildir. Bunun yerine, her
<literal>case</literal> taşıdığı isimde tekil bir nesneyle desteklenir.
Şöyle ki:
</para>
<programlisting role="php">
<![CDATA[
<?php
$a = Deste::Sinekler;
$b = Deste::Sinekler;
$a === $b; // true
$a instanceof Deste; // true
?>
]]>
</programlisting>
<para>
Bu ayrıca, sayılama değerlerin birbirlerinden büyük veya küçük
olamayacağı anlamına da gelir (zaten nesneler arasında böyle bir
karşılaştıma anlamsızdır). Sayılama değerleri ile çalışırken bu
karşılaştırmalar daima &false; döndürür.
</para>
<para>
Bir değer içermeyen <literal>case</literal> türüne "Desteksiz Kılıf"
denir. Sadece desteksiz kılıflar içeren sayılamalara "Desteksiz
Sayılama" denir.
</para>
<para>
Tüm desteksiz kılıflar içerildikleri sayılamayı gerçekleyen
örneklerdir. <literal>enum</literal> türü dahili olarak bir sınıfla
ifade edilir.
</para>
<para>
Tüm kılıflar birer salt-okunur özellik olup <literal>name</literal> harf
büyüklüğüne duyarsız olarak kılıfın kendi ismidir.
</para>
<programlisting role="php">
<![CDATA[
<?php
print Deste::Sinekler->name;
// çıktısı: "Sinekler"
?>
]]>
</programlisting>
<para>
<literal>name</literal> dinamik olarak elde edilmişse, bir enum durumunun
varlığına bakmak veya okumak için <function>defined</function> ve
<function>constant</function> işlevlerini kullanmak da mümkündür. Bununla
birlikte, <link linkend="language.enumerations.backed">Destekli
sayılamaların</link> kullanımı çoğu kullanım durumunda çalışması
gerektiğinden bu önerilmez.
</para>
</sect1>
<sect1 xml:id="language.enumerations.backed">
<title>Destekli Sayılamalar</title>
<para>
Öntanımlı olarak sayıl kılıfların sayıl bir karşılığı yoktur. Basitçe
tekil nesnelerdir. Bununla birlikte, bir sayılama kılıfının bir
veritabanına veya benzer bir veri deposuna giriş-çıkış yapabilmesini
gerektiren çok sayıda durum vardır, dolayısıyla, dahili olarak tanımlanmış
yerleşik bir sayıl (ve dolayısıyla dizgeleştirilebilir) eşdeğerin varlığı
yararlıdır.
</para>
<para>Bir sayılamaya sayıl bir eşdeğer tanımlama sözdizimi:</para>
<programlisting role="php">
<![CDATA[
<?php
enum Deste: string
{
case Kupalar = 'Ku';
case Karolar = 'Ka';
case Sinekler = 'S';
case Maçalar = 'M';
}
?>
]]>
</programlisting>
<para>
Basitçe bir değerle "desteklenmiş" olduğundan sayıl eşdeğeri olan kılıflara
"Destekli Kılıf" denir. Yalnızca destekli kılıflar içeren sayılamalara
"Destekli Sayılama" denir. Destekli bir sayılama sadece
destekli kılıfları içerir, desteksiz kılıf içermez. Desteksiz bir
sayılama ise sadece desteksiz kılıfları içerir, destekli kılıf içermez.
</para>
<para>
Destekli bir sayılama, <literal>int</literal> veya
<literal>string</literal> türünde bir değerle ama daima tek bir türdeki
değerlerle desteklenebilir (yani ya hepsi <literal>int</literal> ya da
hepsi <literal>string</literal> türünde olabilir). Bir sayılama sayıl
bir eşdeğere sahip olarak imlenmişse, tüm kılıflarına açıkça eşsiz birer
değer tanımlanmış olmalıdır. Sayıl eşdeğerler otomatik olarak
üretilmeyecektir (örneğin, sıralı tamsayılar). Destekli kılıflar diğer
kılıflar arasında eşsiz olmalı, aynı sayıl eşdeğere sahip birden fazla
kılıf olmamalıdır. Ancak, bir takma ad oluşturmak amacıyla bir sabite
atanabilir. Bkz: <link
linkend="language.enumerations.constants">Sayılama Sabitleri</link>.
</para>
<para>
Sayıl eşdeğerler sayılların kendileri olabileceği gibi sayıl ifadeleri de
olabilir. Sabitler ve sabit ifadeleri desteklenmez. Yani,
<literal>1 + 1</literal> geçerli, fakat <literal>1 + SOME_CONST</literal>
geçersizdir.
</para>
<para>
Destekli Kılıflar ayrıca salt-okunur özellikler olup,
<literal>value</literal> tanımda belirtilen değerdir.
</para>
<programlisting role="php">
<![CDATA[
<?php
print Deste::Sinekler->value;
// Çıktısı: "S"
?>
]]>
</programlisting>
<para>
<literal>value</literal> özelliğin salt-okunurluğunu zorlamak amacıyla
bir değişkene gönderimli atanamaz. Yani, aşağıdaki örnek bir hata üretir:
</para>
<programlisting role="php">
<![CDATA[
<?php
$deste = Deste::Sinekler;
$ref = &$deste->value;
// hata: Deste::$value özelliğine gönderim sağlanamıyor
?>
]]>
</programlisting>
<para>
Destekli sayılamalar dahili olarak iki ek yöntem sağlayan
<interfacename>BackedEnum</interfacename> arayüzü ile gerçeklenir:
</para>
<simplelist>
<member>
<literal>from(int|string): self</literal> yöntemi bir sayıl değer alır ve
karşılığı olan sayılama kılıfını döndürür. Böyle bir kılıf yoksa
<classname>ValueError</classname> istisnası oluşur. Girdi olarak sayıl
değere güvenildiği ancak karşılığında bir sayılama değerinin
olmadığı durumda uygulamayı durduracak bir hata gerekiyorsa yararlı
olabilir.
</member>
<member>
<literal>tryFrom(int|string): ?self</literal> yöntemi bir sayıl değer alır
ve karşılığı olan sayılama kılıfını döndürür. Böyle bir kılıf yoksa,
yönrem <literal>null</literal> döndürür. Girdi olarak sayıl
değere güvenilmediği durumda geliştirici hatayı kendi ele almak isterse
veya bir öntanımlama yapmak isterse yararlı olabilir.
</member>
</simplelist>
<para>
<literal>from()</literal> ve <literal>tryFrom()</literal> yöntemleri
standart gevşek/katı kodlama kurallarını izler. Gevşek kodlama kipinde, bir
tamsayı veya dizge aktarımı kabul edilebilir ve sistem değeri buna göre
zorlar. Bir gerçel sayı da çalışır ve bu da zorlanır. Katı kodlama kipinde,
bir dizge kılıf değeri durumunda <literal>from()</literal> yöntemine bir
tamsayı (veya gerçel sayı) aktarımı (veya tersi)
<classname>TypeError</classname> istisnasına yol açar. Her iki kipte, tüm
diğer bağımsız değişken türleri <classname>TypeError</classname> istisnasına yol
açar.
</para>
<programlisting role="php">
<![CDATA[
<?php
$record = get_stuff_from_database($id);
print $record['deste'];
$deste = Deste::from($record['deste']);
// Geçersiz veri ValueError yavrulatır: "X" değeri enum "Deste" için geçerli bir sayıl değer değildir
print $deste->value;
$deste = Deste::tryFrom('A') ?? Deste::Sinekler;
// Geçersiz veri null döndürür, yerine Deste::Sinekler kullanılır.
print $deste->value;
?>
]]>
</programlisting>
<para>
<literal>from()</literal> veya <literal>tryFrom()</literal> yöntemini
destekli bir sayılama üzerinde geliştirici kendi tanımlarsa sonuç
ölümcül hata olur.
</para>
</sect1>
<sect1 xml:id="language.enumerations.methods">
<title>Sayılama Yöntemleri</title>
<para>
Sayılamalar (destekli ve desteksiz, her ikiside) yöntemler içerebilir
ve arayüzleri gerçekleyebilir. Bir sayılama, bir arayüzü
gerçekliyorsa bu arayüz için her tür sınaması bu sayılamanın tüm
sınıflarını kabul edecektir.
</para>
<programlisting role="php">
<![CDATA[
<?php
interface Renkli
{
public function renk(): string;
}
enum Deste implements Renkli
{
case Kupalar;
case Karolar;
case Sinekler;
case Maçalar;
// Arayüzle anlaşmayı sağlar.
public function renk(): string
{
return match($this) {
Deste::Kupalar, Deste::Karolar => 'Kırmızı',
Deste::Sinekler, Deste::Maçalar => 'Siyah',
};
}
// bir arayüzün parçası değil; ama geçerli.
public function kesim(): string
{
return "Dörtgen";
}
}
function boya(Renkli $c)
{
/* ... */
}
boya(Deste::Sinekler); // çalışır
print Deste::Karolar->kesim(); // "Dörtgen"
?>
]]>
</programlisting>
<para>
Bu örnekte, dört <literal>Deste</literal> örneğinin hepsi iki yönteme
sahiptir: <literal>renk()</literal> ve <literal>kesim()</literal>. Kod
çağrılır çağrılmaz tür sınamaları yapılır. Bu, diğer nesne örneklerine
uygulanandan farklı değildir.
</para>
<para>
Destekli sayılamada arayüz bildirimi, desteki tür bildiriminden sonra
ele alınır.
</para>
<programlisting role="php">
<![CDATA[
<?php
interface Renkli
{
public function renk(): string;
}
enum Deste: string implements Renkli
{
case Kupalar = 'Ku';
case Karolar = 'Ka';
case Sinekler = 'S';
case Maçalar = 'M';
// arayüzle anlaşmayı sağlar
public function renk(): string
{
return match($this) {
Deste::Kupalar, Deste::Karolar => 'Kırmızı',
Deste::Sinekler, Deste::Maçalar => 'Siyah',
};
}
}
?>
]]>
</programlisting>
<para>
Yöntemin içindeki <literal>$this</literal> değişkeni değer olarak kılıf
örneği alır.
</para>
<para>
Yöntemler keyfi olarak karmaşık olabilir, ancak uygulamada, farklı
durumlara farklı sonuçlar sağlamak için genellikle statik bir değer döner
veya <literal>$this</literal> ile &match; ifadesine eşlenir.
</para>
<para>
Bu durumda, Kırmızı ve Siyah değerleriyle bir RenkliDeste Enum türü
tanımlamak ve bunun yerine onu döndürmek daha iyi bir veri modelleme
uygulaması olacaktır. Ancak bu, örneği daha da karmaşıklaştıracaktır.
</para>
<para>
Yukarıdaki hiyerarşi mantıksal olarak aşağıdaki sınıf yapısına benzer
(bu, çalışan asıl kod olmasa da):
</para>
<programlisting role="php">
<![CDATA[
<?php
interface Renkli
{
public function renk(): string;
}
final class Deste implements UnitEnum, Renkli
{
public const Kupalar = new self('Kupalar');
public const Karolar = new self('Karolar');
public const Sinekler = new self('Sinekler');
public const Maçalar = new self('Maçalar');
private function __construct(public readonly string $name) {}
public function renk(): string
{
return match($this) {
Deste::Kupalar, Deste::Karolar => 'Kırmızı',
Deste::Sinekler, Deste::Maçalar => 'Siyah',
};
}
public function kesim(): string
{
return "Dörtgen";
}
public static function cases(): array
{
// Geçersiz yöntem
// Bir Enum üzerinde cases() yöntemini geliştirici tanımlayamaz.
// "Değer listeleme" bölümüne bakınız.
}
}
?>
]]>
</programlisting>
<para>
Yöntemler public, private veya protected olabilir, ancak uygulamada
private ve protected kalıtıma izin verilmediğinden eşdeğerdir.
</para>
</sect1>
<sect1 xml:id="language.enumerations.static-methods">
<title>Statik Sayılama Yöntemleri</title>
<para>
Sayılamaların statik yöntemleri de olabilir. Statik yöntemlerin
sayılamalar üzerinde kullanımının birincil amacı kurucu
oluşturmaktır. Örnek:
</para>
<programlisting role="php">
<![CDATA[
<?php
enum Boyut
{
case Küçük;
case Normal;
case Büyük;
public static function uzunluğaGöre(int $cm): static
{
return match(true) {
$cm < 50 => static::Küçük,
$cm < 100 => static::Normal,
default => static::Büyük,
};
}
}
?>
]]>
</programlisting>
<para>
Statik yöntemler public, private veya protected olabilirse de kalıtıma izin
verilmediğinden uygulamada private ve protected eşdeğerdir.
</para>
</sect1>
<sect1 xml:id="language.enumerations.constants">
<title>Sayılama Sabitleri</title>
<para>
Sayılamalar public, private veya protected olabilen sabitler içerebilir.
</para>
<para>Bir enum sabiti, bir kılıfa atıfta bulunabilir:</para>
<programlisting role="php">
<![CDATA[
<?php
enum Boyut
{
case Küçük;
case Normal;
case Büyük;
public const Kocaman = self::Büyük;
}
?>
]]>
</programlisting>
</sect1>
<sect1 xml:id="language.enumerations.traits">
<title>Nitelikler</title>
<para>
Sayılamalar, sınıflardaki gibi davranan niteliklerden yararlanabilir.
Ancak, bir sayılama içinde kullanılan niteliklerin özelliklerinin
olmamasına dikkat edilmelidir; sadece yöntemler ve statik yöntemler
içerebilir. Özellikleri olan bir nitelik ölümcül hata ile sonuçlanır.
</para>
<programlisting role="php">
<![CDATA[
<?php
interface Renkli
{
public function renk(): string;
}
trait Dörtgen
{
public function kesim(): string {
return "Dörtgen";
}
}
enum Deste implements Renkli
{
use Dörtgen;
case Kupalar;
case Karolar;
case Sinekler;
case Maçalar;
public function renk(): string
{
return match($this) {
Deste::Kupalar, Deste::Karolar => 'Kırmızı',
Deste::Sinekler, Deste::Maçalar => 'Siyah',
};
}
}
?>
]]>
</programlisting>
</sect1>
<sect1 xml:id="language.enumerations.expressions">
<title>Sabit ifadelerinde sayılama değerleri</title>
<para>
Kılıflar enum üzerinde sabitler olarak temsil edildiğinden, çoğu sabit
ifadesinde statik değerler olarak kullanılabilir: özellik öntanımlıları,
statik değişken öntanımlıları, bağımsız değişken öntanımlıları, küresel ve sınıf
sabitlerinin değerleri. Ancak diğer kılıf değerlerinde kullanılamaz, sadece
enum sabitleri bir kılıfa atıfta bulunabilir.
</para>
<para>
Ancak, sonuç değerinin belirleyici olduğunu veya yöntem çağrılarının yan
etkilerden arınmış olduğunu kesinlikle garanti edemediğimiz için,
sayılamalarda <classname>ArrayAccess</classname> gibi örtük sihirli
yöntem çağrılarına statik veya sabit tanımlar içinde izin verilmez. İşlev
çağrıları, yöntem çağrıları ve özellik erişimi, sabit ifadeler içinde
geçersiz işlemler olarak kalmaya devam eder.
</para>
<programlisting role="php">
<![CDATA[
<?php
// Bu tamamen geçerli bir sayılama tanımıdır.
enum Direction implements ArrayAccess
{
case Up;
case Down;
public function offsetExists($offset): bool
{
return false;
}
public function offsetGet($offset): mixed
{
return null;
}
public function offsetSet($offset, $value): void
{
throw new Exception();
}
public function offsetUnset($offset): void
{
throw new Exception();
}
}
class Foo
{
// Buna izin verilir.
const DOWN = Direction::Down;
// Buna izin verilmez, belirleyici olmayabilir.
const UP = Direction::Up['short'];
// Ölümcül Hata: enum üzerinde sabit ifadesi içinde [] kullanılamaz
}
// Bu, bir sabit ifadesi olmadığından tamamen geçerlidir.
$x = Direction::Up['short'];
var_dump("\$x: " . var_export($x, true));
$foo = new Foo();
?>
]]>
</programlisting>
</sect1>
<sect1 xml:id="language.enumerations.object-differences">
<title>Nesnelerden farkları</title>
<para>
Sayılamalar, sınıflar ve nesnelerde yerleşik bulunabilirse de,
nesnelerle ilgili işlevselliğin tamamını kullanamaz. Özellikle,
sayılamalar durumlu olamaz.
</para>
<simplelist>
<member>Kurucular ve yıkıcılar kullanılamaz.</member>
<member>Kalıtım desteklenmez. Sayılamalar ne genişletebilir ne de
genişletilebilir.</member>
<member>Statik ve nesne özelliklere izin verilmez.</member>
<member>Bir sayılamanın kopyalanması, kılıfların tekil örnekler
olması gerektiğinden desteklenmez.</member>
<member>Aşağıda sıralananlar dışında kalan
<link linkend="language.oop5.magic">Sihirli yöntemlere</link> izin
verilmez.</member>
<member>Sayılamalar kullanılmadan önce bildirilmelidir.</member>
</simplelist>
<para>
Aşağıdaki nesne işlevselliği kullanılabilir ve diğer nesnelerdeki
davranış elde edilir:
</para>
<simplelist>
<member>Public, private ve protected yöntemler.</member>
<member>Public, private ve protected static yöntemler.</member>
<member>Public, private ve protected sabitler.</member>
<member>Sayılamalar çok sayıda arayüz gerçekleyebilir.</member>
<member>
Sayılamalar ve kılıfların kendilerine ekli
<link linkend="language.attributes">öznitelikleri</link> olabilir.
<constant>TARGET_CLASS</constant> hedef süzgeci sayılamaların
kendilerini içerir. <constant>TARGET_CLASS_CONST</constant> hedef süzgeci
ise sayılama kılıflarını içerir.
</member>
<member>
<link linkend="object.call">__call</link>,
<link linkend="object.callstatic">__callStatic</link>,
ve <link linkend="object.invoke">__invoke</link> sihirli yöntemleri
</member>
<member><constant>__CLASS__</constant> ve <constant>__FUNCTION__</constant>
sabitleri normal olarak davranır.</member>
</simplelist>
<para>
Bir sayılama türündeki <literal>::class</literal> sihirli sabiti,
tamamen bir nesnedeki gibi isim alanlı tür adı olarak değerlendirilir. Bir
kılıf örneğindeki <literal>::class</literal> sihirli sabiti ise, o türün
tekil örneği olduğu için sayılama olarak değerlendirilir.
</para>
<para>
Ayrıca, sayılama kılıfları doğrudan <literal>new</literal> ile
örneklenemediği gibi yansıtma içinde
<methodname>ReflectionClass::newInstanceWithoutConstructor</methodname> ile
de örneklenemez.
</para>
<programlisting role="php">
<![CDATA[
<?php
$trefl = new Deste();
// Hata: enum Deste örneklenemez
$kör = (new ReflectionClass(Deste::class))->KurucusuzYeniÖrnek()
// Hata: enum Deste örneklenemez
?>
]]>
</programlisting>
</sect1>
<sect1 xml:id="language.enumerations.listing">
<title>Değer Listeleme</title>
<para>
Destekli ya da desteksiz, sayılamaların her ikisi de
<interfacename>UnitEnum</interfacename> adlı dahili bir arayüzü gerçekler.
<literal>UnitEnum</literal> arayüzü <literal>cases()</literal> statik
yöntemini içerir. <literal>cases()</literal> yöntemi, bildirim sırasında
tanımlanmış tüm kılıfları içeren bir dizi döndürür.
</para>
<programlisting role="php">
<![CDATA[
<?php
Deste::cases();
// Şunları üretir: [Deste::Kupalar, Deste::Karolar, Deste::Sinekler, Deste::Maçalar]
?>
]]>
</programlisting>
<para>
Bir sayılamada <literal>cases()</literal> yöntemini kendiniz
tanımlarsanız ölümcül bir hata alırsınız.
</para>
</sect1>
<sect1 xml:id="language.enumerations.serialization">
<title>Dizgeleştirme</title>
<para>
Sayılamaların dizgeleştirmesi nesnelerden farklıdır. Özellikle,
kendilerine özgü bir dizgeleştirme kodu olarak sayılama kılıfı ismini
belirten <literal>"E"</literal> koduna sahiptir. Nesneleştirme sırasında
kod bunu mevcut tekil değeri bir değişkene atamakta kullanır. Sonuçta
aşağıdaki gibi bir durumun gerçeklenmesi sağlanır:
</para>
<programlisting role="php">
<![CDATA[
<?php
Deste::Kupalar === unserialize(serialize(Deste::Kupalar));
print serialize(Deste::Kupalar);
// E:14:"Deste::Kupalar";
?>
]]>
</programlisting>
<para>
Nesneleştirme sırasında bir sayılama ve kılıfın eşleşeceği
dizgeleştirilmiş bir değer yoksa bir uyarı çıktılayıp
&false; döndürülür.
</para>
<para>
Desteksiz bir sayılamayı JSON'a dizgeleştirme bir hataya yol açar.
Destekli bir sayılamayı JSON'a dizgeleştirme ise uygun türdeki sayıl
değeri ile gösterilir. Her iki davranış
<classname>JsonSerializable</classname> gerçeklenerek geçersiz kılınabilir.
</para>
<para>
<function>print_r</function> için, sayılama kılıfı çıktısı,
karışıklığı azaltmak için nesnelerdekinden oldukça farklıdır.
</para>
<programlisting role="php">
<![CDATA[
<?php
enum Foo {
case Bar;
}
enum Baz: int {
case Beep = 5;
}
print_r(Foo::Bar);
print_r(Baz::Beep);
/* Çıktısı:
Foo Enum (
[name] => Bar
)
Baz Enum:int {
[name] => Beep
[value] => 5
}
*/
?>
]]>
</programlisting>
</sect1>
<sect1 xml:id="language.enumerations.object-differences.inheritance">
<title>- Sayılamalar neden genişletilemez?</title>
<simpara>
Sınıfların yöntemleri üzerinde sözleşmeleri vardır:
</simpara>
<programlisting role="php">
<![CDATA[
<?php
class A {}
class B extends A {}
function foo(A $a) {}
function bar(B $b) {
foo($b);
}
?>
]]>
</programlisting>
<simpara>
Bu kod tür açısından güvenlidir, çünkü B, A'nın sözleşmesini takip eder ve
az/çok-özgüllüğün büyüsü aracılığıyla, istisnalar dışında, yöntemlerden
beklentiler korunur.
</simpara>
<simpara>
Sayılamalar yöntemlerle değil kılıflarla yönetilir:
</simpara>
<programlisting role="php">
<![CDATA[
<?php
enum ErrorCode {
case SOMETHING_BROKE;
}
function quux(ErrorCode $errorCode)
{
// Bu kod tüm kılıfları kapsıyor gibi görünüyor
match ($errorCode) {
ErrorCode::SOMETHING_BROKE => true,
}
}
?>
]]>
</programlisting>
<simpara>
<code>quux</code> işlevindeki &match; deyimi, <code>ErrorCode</code>
sayılamasındaki tüm kılıfları kapsayacak şekilde statik olarak incelenebilir.
</simpara>
<simpara>
Ancak, sayılamaların genişletilmesine izin verildiği varsayılırsa:
</simpara>
<programlisting role="php">
<![CDATA[
<?php
// Sayılamaların değişmez olmadığı deneysel kod.
// Dikkat, bu kod aslında PHP'de çalışmaz.
enum MoreErrorCode extends ErrorCode {
case PEBKAC;
}
function fot(MoreErrorCode $errorCode) {
quux($errorCode);
}
fot(MoreErrorCode::PEBKAC);
?>
]]>
</programlisting>
<simpara>
Normal kalıtım kurallarına göre, diğerini genişleten bir sınıf tür
denetimini geçecektir.
</simpara>
<simpara>
<code>quux()</code> içindeki &match; deyiminin artık tüm kılıfları
kapsamaması sorun olur. <code>MoreErrorCode::PEBKAC</code> hakkında
bilgisi olmadığı için &match; deyimi bir istisna oluşturur.
</simpara>
<simpara>
Bu nedenle sayılamalar değişmezdir ve genişletilemez.
</simpara>
</sect1>
<sect1 xml:id="language.enumerations.examples">
&reftitle.examples;
<para>
<example>
<title>- Basit sınırlı değerler</title>
<programlisting role="php">
<![CDATA[
<?php
enum Sırala
{
case Art;
case Azal;
}
function sorgu($alanlar, $süzgeç, Sırala $sırala = Sırala::Art)
{
/* ... */
}
?>
]]>
</programlisting>
<para>
<literal>sorgu()</literal> işlevi, $sırala'nın Sırala::Art veya
Sırala::Azal olduğunun garanti edildiği bilgisiyle artık güvenli bir
şekilde ilerleyebilir. Başka herhangi bir değer
<classname>TypeError</classname> ile sonuçlanırdı, bu nedenle daha fazla
hata denetimi veya sınaması yapmak gerekmez.
</para>
</example>
</para>
<para>
<example>
<title>- Daha ileri özel değerler</title>
<programlisting role="php">
<![CDATA[
<?php
enum UserStatus: string
{
case Pending = 'B';
case Active = 'E';
case Suspended = 'A';
case CanceledByUser = 'V';
public function yafta(): string
{
return match($this) {
static::Pending => 'Beklemede',
static::Active => 'Etkin',
static::Suspended => 'Askıda',
static::CanceledByUser => 'Kullanıcı Vazgeçti',
};
}
}
?>
]]>
</programlisting>
<para>
Bu örnekte kullanıcının durumu, özellikle şu durumlardan biri olabilir:
<literal>UserStatus::Pending</literal>,
<literal>UserStatus::Active</literal>,
<literal>UserStatus::Suspended</literal> veya
<literal>UserStatus::CanceledByUser</literal>.
<literal>UserStatus</literal> türünde bağımsız değişken içeren bir işlev sadece
bu dört değerden birini kabul edebilir.
</para>
<para>
Dört değer için, insan okuyabilir dizge döndüren
<literal>yafta()</literal> yöntemi kullanılmıştır. Bu dizge,
bir veritabanı alanında veya HTML seçim kutusunda kullanılabilen
"makine adı" sayıl eşdeğeri olan dizgeden farklı ve bağımsızdır.
</para>
<programlisting role="php">
<![CDATA[
<?php
foreach (UserStatus::cases() as $case) {
printf('<option value="%s">%s</option>\n', $case->value, $case->yafta());
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>