A linguagem
uses com apelido e seleção de nomes
uses A as B e uses A (T1, T2 as U): evitar colisões de nomes sem abrir mão do módulo.
O que é e por que existe#
Dois módulos que declaram o mesmo nome (Sum, TPoint) colidem quando entram soltos no escopo. O uses ganhou duas formas que resolvem isso sem renomear nada nos módulos:
uses Geometry as G; // nada de Geometry entra solto: tudo é G.Nome
uses Geometry (TPoint as TGeoPoint); // só TPoint entra, e com outro nome
uses Geometry (TPoint, Sum); // seleção sem renomear| Forma | Efeito |
|---|---|
uses A as B | o módulo inteiro fica acessível só por B.Nome |
uses A (T1, T2) | só T1 e T2 entram no escopo, com os nomes originais |
uses A (T1, T2 as U) | só os citados entram; T2 passa a se chamar U |
As formas se combinam na mesma cláusula, separadas por vírgula.
program UsesAlias;
// Demo: `uses` com apelido (`as`) e seleção de nomes.
// uses A as B -> nada de A entra solto no escopo; tudo se acessa por B.Nome
// uses A (T1, T2 as U) -> só T1 e T2 entram no escopo (T2 com o nome U)
// Útil para evitar colisões: aqui o programa tem a sua própria Sum, e a do módulo continua acessível.
uses System.Remainder,
Geometry as G, // G.Sum, G.Describe, G.TPoint
Geometry (TPoint as TGeoPoint); // só TPoint entra no escopo, com outro nome
// colide com Geometry.Sum se o módulo fosse usado sem apelido; assim, não há conflito
function Sum(A, B: Int32): Int32;
begin
Exit(A * 100 + B);
end function;
var
LPoint: TGeoPoint; // nome escolhido na seleção
LOther: G.TPoint; // o mesmo tipo, pelo apelido
begin
LPoint.X := 1;
LOther.Y := 2;
WriteLn('Sum do programa: ', Sum(1, 2));
WriteLn('G.Sum do módulo: ', G.Sum(1, 2));
WriteLn(G.Describe);
WriteLn('X=', LPoint.X, ' Y=', LOther.Y);
end.module Geometry;
// Módulo de apoio do demo 52. Sem seções interface/implementation: cada declaração
// diz se é `public` (visível a quem usa o módulo) ou `private` (omissão).
// Os nomes Sum, Describe e TPoint colidem de propósito com os do programa.
public type
TPoint = record
public
X, Y: Int32;
end record;
public function Sum(A, B: Int32): Int32;
begin
Exit(A + B);
end;
public function Describe: UString;
begin
Exit('módulo Geometry');
end;
end.Sum do programa: 102
G.Sum do módulo: 3
módulo Geometry
X=1 Y=2Demo 52. O programa tem a sua Sum e o módulo também; o apelido G deixa as duas à mão.
No exemplo, Sum(1, 2) é a do programa (resultado 102) e G.Sum(1, 2) é a do módulo (resultado 3). TGeoPoint e G.TPoint são o mesmo tipo, com dois nomes.
Por baixo#
Num módulo (module X;) não existem interface e implementation: cada declaração é public ou private, e a omissão é private. Veja Módulos e visibilidade.
Armadilhas#
- Depois de
uses Geometry as G, citarTPointsolto é "identificador não declarado": o nome só existe comoG.TPoint. - Uma expressão constante ainda não aceita
Alias.Const(const K = G.Base + 1;dá "valor constante desconhecido"). O limite vale também sem apelido, comUnit.Const. Use uma constante local. - Os genéricos aceitam o nome qualificado:
TList<G.TPoint>(alias em genéricos veio no 2º pacote).
Veja também#
- Módulos e visibilidade, Ciclos entre módulos, Regiões e forward.
- Demo
52-uses-apelido.