Enumerado

1. Tipos enumerados (Enumerated Type)

Os enumerados do Pascal são tipos opacos com ótima encapsulação e são usados muito mais frequentemente no desenvolvimento diário do que os enumerados de outras linguagens.

Sintaxe básica de declaração

type
  TAnimalKind = (akDuck, akCat, akDog);

Convenção de código: adicionar um prefixo de duas letras abreviado do nome do tipo em cada constante enumerada

  • ak = Animal Kind (abreviação de TAnimalKind)
  • Finalidade: constantes enumeradas pertencem ao namespace global da unidade por padrão. O prefixo reduz drasticamente conflitos de nomes com outras variáveis e tipos customizados.

A letra T no início de TAnimalKind é opcional sintaticamente, é apenas uma convenção do mercado. Recomenda-se mantê-la para identificar rapidamente que se trata de um tipo enumerado.

type
  AnimalKind = (akDuck, akCat, akDog); // Sem T, sintaxe válidaCode language: JavaScript (javascript)

Observações complementares:

  1. Nomes iguais não causam erro de compilação imediato; unidades diferentes podem declarar identificadores idênticos;
  2. Mesmo assim, evite conflitos de nome para melhor legibilidade e buscas globais (grep).

Enumerados com escopo (enumerados qualificados, {$scopedenums on})

A diretiva do compilador {$scopedenums on} isola as constantes enumeradas dentro do seu tipo, evitando poluir o namespace global

Desativado por padrão
{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}
program EnumDemo;

type TAnimalKind = (akDuck, akCat);

var k: TAnimalKind;

begin
  k := akDuck; // Usar constante diretamente, sem TAnimalKind.
  WriteLn(k); //Exibe akDuck
end.Code language: PHP (php)

Como comentamos antes, o código começa a ser executado na palavra-chave begin.

Usar o prefixo ak é uma boa prática para evitar conflitos; omitir ele não gera erros.

{$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)

Com {$scopedenums on} ativado é obrigatório escrever «NomeDoTipo.»

  1. Todo acesso precisa do qualificador de tipo: TAnimalKind.akDuck
  2. O prefixo ak não é mais necessário; as constantes podem ser escritas simplesmente como Duck, Cat, Dog
{$scopedenums on}
type
  TAnimalKind = (Duck, Cat, Dog);
var
  Kind: TAnimalKind;
begin
  Kind := TAnimalKind.Duck; // Qualificador de tipo obrigatório
end;Code language: PHP (php)

Se omitir o qualificador de tipo

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

type TAnimalKind = (Duck, Cat);
var k: TAnimalKind;
begin
  k := Duck; // Sem TAnimalKind.
  WriteLn(k);
end.Code language: PHP (php)

Ocorre um erro de compilação

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)

Ao adicionar o qualificador de tipo

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

type TAnimalKind = (Duck, Cat);
var k: TAnimalKind;
begin
  k := TAnimalKind.Duck; // Com qualificador completo
  WriteLn(k);
end.Code language: PHP (php)

O código compila normalmente

Conversão explícita entre enumerados e inteiros

Enumerados são tipos opacos; não é possível atribuir valores diretamente entre enumerados e inteiros, é obrigatório fazer conversão manual:

  1. Enumerado → Inteiro: Ord(variávelEnumerada)
  2. Inteiro → Enumerado: conversão de tipo explícita TAnimalKind(valorInteiro)
  3. Sempre valide o intervalo antes de converter um inteiro para enumerado: faixa válida 0 ~ Ord(High(TipoEnumerado))
type
  TAnimalKind = (akDuck, akCat, akDog);
var
  Kind: TAnimalKind;
  Num: Integer;
begin
  Kind := akCat;
  Num := Ord(Kind); // akCat tem ordinal 1, Num=1

  Num := 2;
  // Validar intervalo antes da conversão
  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)

Enumerado

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *