Identificadores qualificados por unidade

Semelhante aos namespaces do C++, Java e C#

Conflitos de identificadores com nomes iguais

Múltiplas unidades podem definir tipos / funções / variáveis com o mesmo nome. As unidades que aparecem depois na lista uses sombreiam identificadores de mesmo nome das unidades anteriores.

Sintaxe de qualificação por unidade

NomeUnidade.Identificador especifica explicitamente a origem, força o uso da definição da unidade indicada e resolve conflitos de sombreamento.

Os dois trechos de uses funcionam de forma independente

  • interface uses:apenas vale para a seção de interface;
  • implementation uses:apenas vale para a seção de implementação. Identificadores de unidades da seção de implementação sombreiam aqueles de mesmo nome das unidades da interface.

Exemplo

Crie uma unidade chamada Graphics.pas

unit Graphics;
{$mode objfpc}{$H+}

interface

type
  TColor = LongInt;
const
  clYellow = 10;
function Red(C:TColor):Integer;
function Green(C:TColor):Integer;
function Blue(C:TColor):Integer;

implementation
function Red(C:TColor):Integer; begin Result:=C shr 16; end;
function Green(C:TColor):Integer; begin Result:=(C shr 8) and 255; end;
function Blue(C:TColor):Integer; begin Result:=C and 255; end;

end.Code language: JavaScript (javascript)

Depois crie outra unidade GoogleMapsEngine.pas

unit GoogleMapsEngine;
{$mode objfpc}{$H+}

interface
type
  TColor = string; // Tipo completamente diferente de Graphics.TColor

implementation

end.Code language: PHP (php)

Temos dois tipos TColor com o mesmo nome, mas estruturas distintas

Agora escreva o programa principal

program showcolor;
{$mode objfpc}{$H+}
{$apptype CONSOLE}

uses Graphics, GoogleMapsEngine;

var
  // Color: TColor; // Erro: usa GoogleMapsEngine.TColor (tipo string), que vem depois
  Color: Graphics.TColor; // Correto, qualificação explícita da unidade

begin
  Color := clYellow;
  WriteLn(Red(Color), ' ', Green(Color), ' ', Blue(Color));
  ReadLn;
end.Code language: PHP (php)

Compile e execute

Se omitir o prefixo Graphics., o padrão será GoogleMapsEngine.TColor. Por quê?

No projeto principal, a linha é uses Graphics, GoogleMapsEngine;. Como GoogleMapsEngine é declarado depois, quando houver identificadores TColor duplicados, o compilador resolve por padrão o tipo da unidade posterior, ou seja GoogleMapsEngine.TColor.

Para diferenciar os dois, use Graphics.TColor explicitamente. Funciona como os namespaces e elimina conflitos de nomes.

Exemplo incorreto

Tipos TColor incompatíveis entre a seção de interface e implementação causam erro de compilação

Crie uma nova unidade UnitUsingColors.pas

unit UnitUsingColors;
{$mode objfpc}{$H+}
interface
uses Graphics;
procedure ShowColor(const Color: TColor);

implementation
uses GoogleMapsEngine; // O TColor da implementação sombreia o da interface

// Aqui TColor se refere a GoogleMapsEngine.TColor
procedure ShowColor(const Color: TColor); 
begin
end;

end.Code language: JavaScript (javascript)

Referencie essa unidade no programa principal mydemo.dpr

program showcolor;
{$mode objfpc}{$H+}
{$apptype CONSOLE}

uses UnitUsingColors;

begin

end.Code language: PHP (php)

Basta apenas referenciar a unidade, sem precisar chamar suas funções ou procedimentos. Se nenhum trecho dela for invocado, o compilador pula a compilação de UnitUsingColors.pas.

Análise da causa do erro (visão do compilador):

// Assinatura da interface
procedure ShowColor(const Color: Graphics.TColor);
// Assinatura da implementação
procedure ShowColor(const Color: GoogleMapsEngine.TColor);Code language: JavaScript (javascript)

Modifique o código como abaixo

unit UnitUsingColors;
{$mode objfpc}{$H+}
interface
uses Graphics;
procedure ShowColor(const Color: TColor);
implementation
uses GoogleMapsEngine;
// Especifique explicitamente TColor da Graphics para evitar sombreamento por tipo homônimo
procedure ShowColor(const Color: Graphics.TColor);
begin
end;
end.Code language: JavaScript (javascript)
unit UnitUsingColors;
{$mode objfpc}{$H+}
interface
uses Graphics;
procedure ShowColor(const Color: TColor);
implementation
uses GoogleMapsEngine;
// Declare Graphics.TColor explicitamente para unificar o tipo
procedure ShowColor(const Color: Graphics.TColor);
begin
  WriteLn(Red(Color), Green(Color), Blue(Color));
end;
end.Code language: JavaScript (javascript)

Conclusão

Qualificação de unidade NomeUnidade.Identificador permite controlar exatamente a origem dos tipos sem alterar a ordem dos comandos uses, evitando conflitos de nomes.

Identificadores qualificados por unidade

Deixe um comentário

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