PHPCon Poland 2024

列挙型の基礎

列挙型はクラスに似ていますし、 クラスやインターフェイス、トレイトと名前空間を共有します。 列挙型はオートローディングも可能です。 列挙型は新しい型を定義しますが、 固定の、限られた数の有効な値を持ちます。

<?php

enum Suit
{
case
Hearts;
case
Diamonds;
case
Clubs;
case
Spades;
}
?>

上記の宣言によって、新しい列挙型 Suit が作られますが、 これが持つ有効な値は4つだけです。 Suit::HeartsSuit::DiamondsSuit::Clubs、そして Suit::Spades です。 これらの有効な値のうち、ひとつだけを変数に代入できます。 関数は列挙型に対する型チェックを行えますし、 その場合は列挙型の値だけが渡せます。

<?php

function pick_a_card(Suit $suit)
{
/* ... */
}

$val = Suit::Diamonds;

// OK
pick_a_card($val);

// OK
pick_a_card(Suit::Clubs);

// TypeError: pick_a_card(): Argument #1 ($suit) must be of type Suit, string given
pick_a_card('Spades');
?>

列挙型は、0個以上の case を定義できます。 case を定義する数に上限はありません。 case が0個の列挙型も文法的には有効ですが、役に立ちません。

列挙型の case は、PHP のラベルと同じ規則に従います。 定数 のページを参照ください。

デフォルトでは、case は本質的にスカラーの値に依存していません。 つまり、Suit::Hearts"0" に等しくないということです。 むしろ、それぞれの case はその名前が付いたシングルトンオブジェクトです。 以下のコードがそれを示しています:

<?php

$a
= Suit::Spades;
$b = Suit::Spades;

$a === $b; // true

$a instanceof Suit; // true
?>

このことは、列挙型の値は決して <> で比較できないことも意味しています。 なぜなら、それらの比較をオブジェクトで行っても無意味だからです。 列挙型の値を使ってこれらの比較を行っても、常に false を返します。

関連するデータのない、こうしたタイプの case を、 "Pure Case" と呼びます。 Pure Case のみを含む列挙型を、"Pure Enum" と呼びます。

全ての Pure Case は、その列挙型のインスタンスとして実装されています。 列挙型は内部的にクラスとして表現されます。

全ての case は読み取り専用のプロパティ name を持ちます。 これは大文字小文字が区別される、case そのものの名前です。

<?php

print Suit::Spades->name;
// "Spades" と表示
?>

列挙型の名前を動的に取得している場合、 case の存在を確認したり、読み取る用途として defined()constant() 関数が使えます。 しかしながら、これらの関数の利用はおすすめできません。 なぜなら、 Backed Enum で大半の用途を満たせるはずだからです。

add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top