1
0
mirror of https://github.com/php/doc-tr.git synced 2026-03-23 23:02:09 +01:00
Files
archived-doc-tr/language/enumerations.xml
2024-09-09 18:25:17 +03:00

1024 lines
28 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->