열거형

1. 열거형(Enumerated Type)

Pascal의 열거형은 캡슐화 수준이 높은불투명 타입으로, 실무 개발 환경에서 다른 언어의 열거형보다 훨씬 자주 사용됩니다.

기본 정의 문법

type
  TAnimalKind = (akDuck, akCat, akDog);

코딩 규칙: 열거 상수 이름에타입 약자 두 글자 접두사를 붙입니다

  • ak = Animal Kind(TAnimalKind의 약자)
  • 사용 목적: 열거 상수는 기본적으로 유닛 전역 네임스페이스에 포함되므로 접두사를 붙여 다른 변수나 타입과 이름 충돌 가능성을 크게 낮춥니다.

TAnimalKind 맨 앞의 T는 문법상 생략할 수 있지만 업계 표준 관습이므로 붙이는 것을 권장합니다. 한눈에 열거형임을 알 수 있기 때문입니다.

type
  AnimalKind = (akDuck, akCat, akDog); // T를 생략해도 문법상 유효Code language: JavaScript (javascript)

추가 설명:

  1. 동일한 식별자가 존재한다고 바로 컴파일 오류가 발생하지 않으며, 서로 다른 유닛에 같은 이름을 선언할 수 있습니다;
  2. 하지만 코드 가독성과 전역 텍스트 검색(grep) 편의성을 고려해 이름 충돌을 미리 피하는 게 좋습니다.

범위 지정 열거형(한정 열거, {$scopedenums on})

컴파일러 지시자 {$scopedenums on}를 사용하면 열거 상수를 타입 내부로 격리해 전역 네임스페이스를 오염시키지 않습니다

기본 설정은 비활성화
{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}
program EnumDemo;

type TAnimalKind = (akDuck, akCat);

var k: TAnimalKind;

begin
  k := akDuck; // TAnimalKind. 없이 상수를 직접 적을 수 있음
  WriteLn(k); //출력: akDuck
end.Code language: PHP (php)

앞서 설명했듯이 이 코드는 begin 키워드부터 실행됩니다.

ak 접두사를 붙이면 충돌 방지에 유리하며, 접두사를 빼도 컴파일 오류가 생기지 않습니다.

{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}

program EnumDemo;

type TAnimalKind = (Duck, Cat);

var k: TAnimalKind;

begin
  k := Duck; 
  WriteLn(k);//Duck
end.Code language: PHP (php)

{$scopedenums on} 활성화 시 반드시「타입명.」을 붙여야 함

  1. 접근할 때 타입 한정자를 필수로 작성: TAnimalKind.akDuck
  2. ak 접두사가 더 이상 필요하지 않으며 상수를 Duck, Cat, Dog로 간소화할 수 있음
{$scopedenums on}
type
  TAnimalKind = (Duck, Cat, Dog);
var
  Kind: TAnimalKind;
begin
  Kind := TAnimalKind.Duck; // 타입 한정자 필수 기입
end;Code language: PHP (php)

타입 한정자를 생략할 경우

{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}
{$scopedenums on}
program EnumDemo;

type TAnimalKind = (Duck, Cat);
var k: TAnimalKind;
begin
  k := Duck; // TAnimalKind. 한정자가 누락됨
  WriteLn(k);
end.Code language: PHP (php)

컴파일 오류가 발생합니다

D:\fpcdemo>fpc mydemo.dpr
Free Pascal Compiler version 3.2.2 [2021/05/15] for i386
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling mydemo.dpr
mydemo.dpr(9,8) Error: Identifier not found "Duck"
mydemo.dpr(11,4) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: C:\FPC\3.2.2\bin\i386-Win32\ppc386.exe returned an error exitcodeCode language: CSS (css)

타입 한정자를 추가하면

{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}
{$scopedenums on}
program EnumDemo;

type TAnimalKind = (Duck, Cat);
var k: TAnimalKind;
begin
  k := TAnimalKind.Duck; // 완전한 타입 한정자 기입
  WriteLn(k);
end.Code language: PHP (php)

정상적으로 컴파일됩니다

열거형과 정수 강제 형변환

열거형은불투명 타입으로 분류되므로 정수와 직접 값을 대입할 수 없고 수동으로 강제 변환해야 합니다:

  1. 열거형 → 정수: Ord(열거변수)
  2. 정수 → 열거형: 강제 형변환 TAnimalKind(정수값)
  3. 정수를 열거형으로 변환하기 전 반드시 값 범위를 검증하세요: 유효 구간 0 ~ Ord(High(열거타입))
type
  TAnimalKind = (akDuck, akCat, akDog);
var
  Kind: TAnimalKind;
  Num: Integer;
begin
  Kind := akCat;
  Num := Ord(Kind); // akCat 서수는 1, Num=1

  Num := 2;
  // 범위 검증 후 변환 실행
  if (Num >= 0) and (Num <= Ord(High(TAnimalKind))) then
    Kind := TAnimalKind(Num);
end;Code language: JavaScript (javascript)
{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}

program EnumDemo;

type
  TAnimalKind = (akDuck, akCat, akDog);
var
  Kind: TAnimalKind;
  Num: Integer;
begin
  Kind := akCat;
  Num := Ord(Kind); // akCat index is 1,Num=1

  Num := 2;

  if (Num >= 0) and (Num <= Ord(High(TAnimalKind))) then
    Kind := TAnimalKind(Num);

  WriteLn(Num);//2
end.Code language: PHP (php)

열거형

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다