기본 열거형

기본 열거형 (Basic enumerations)

기본 열거형

열거형(Enum)은 클래스와 비슷해요. 그래서 클래스, 인터페이스, 트레이트와 같은 네임스페이스를 공유하고, 같은 방식으로 자동 로드(autoload)도 됩니다. 열거형은 새로운 타입을 정의하는데, 그 타입은 가질 수 있는 유효한 값의 개수가 고정되고 제한적이에요.

<?php

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

이 선언은 Suit라는 이름의 새 열거형 타입을 만드는데, 이 타입은 네 개의 값만 가질 수 있어요. 바로 Suit::Hearts, Suit::Diamonds, Suit::Clubs, Suit::Spades입니다. 변수에는 이 유효한 값 중 하나만 할당할 수 있고요, 함수도 열거형 타입으로 타입 체크를 할 수 있어요. 그 경우 해당 타입의 값만 인자로 넘길 수 있죠.

<?php

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

function pick_a_card(Suit $suit)
{
    var_dump($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');

열거형은 case 정의를 0개 이상 가질 수 있고, 개수에 최대 제한은 없어요. case가 0개인 열거형도 문법상으로는 유효하지만, 실용적인 가치는 거의 없죠.

열거형의 case에는 PHP의 다른 레이블(label)과 동일한 문법 규칙이 적용돼요. 자세한 내용은 상수(Constants) 문서를 참고하세요.

기본적으로 case는 스칼라 값에 연결(backed)되어 있지는 않아요. 즉 Suit::Hearts"0"과 같지 않죠. 대신 각 case는 그 이름을 가진 싱글턴 객체에 의해 뒷받침돼요. 이 말은 곧 이런 의미예요:

<?php

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

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

if ($a === $b) {
    print "Suits match using ===\n";
}

if ($a instanceof Suit) {
    print "Suits match using instanceof\n";
}

if ($a !== 'Spades') {
    print "Suit does not match the string\n";
}

이건 또 열거형 값이 서로 <> 비교가 절대 성립하지 않는다는 뜻이기도 해요. 객체끼리의 그런 비교는 의미가 없으니까요. 열거형 값을 비교할 때 <, > 연산은 항상 false를 반환합니다.

이렇게 관련된 데이터가 없는 case를 **"순수 case(Pure Case)"**라고 불러요. 순수 case만으로 이루어진 열거형을 **순수 열거형(Pure Enum)**이라고 하고요.

모든 순수 case는 자기 열거형 타입의 인스턴스로 구현돼요. 그리고 그 열거형 타입은 내부적으로 클래스로 표현됩니다.

모든 case에는 **읽기 전용 속성 name**이 있는데, 여기에는 case 자신의 이름이 대소문자를 구분한 채 그대로 담겨 있어요.

<?php

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

print Suit::Spades->name;
// prints "Spades"

case의 이름을 동적으로 얻어야 한다면 defined()constant() 함수로 case의 존재를 확인하거나 값을 읽을 수도 있어요. 다만 이 방법은 잘 쓰이지 않아요. 대부분의 경우 Backed 열거형(Backed enums)을 사용하는 편이 더 낫기 때문이죠.