Pergunta

Usando D2010, eu gostaria de fazer algo parecido com isto:

procedure SizeArray(var aArr: array of integer; aSize: integer);
begin
  SetLength(aArr,aSize);
end;

Mas isso não compilar. Porque o meu parâmetro "AARR" não é uma matriz dinâmica, é um parâmetro de matriz aberta. E SetLength não pode ser chamado sobre ele. A única maneira que eu conheço para forçar o parâmetro a ser uma matriz dinâmica é dar-lhe um nome de tipo, assim:

type
  TIntArray = array of integer;

procedure SizeArray(var aArr: TIntArray; aSize: integer);
begin
  SetLength(aArr,aSize);
end;

E agora os compila o código. E ele funciona muito bem, em sua maior parte, mas esta falha:

procedure Test;
var
  a : array of integer;
begin
  SizeArray(a,5);
end;

Por tipos de parâmetros reais e formais var deve ser idêntico eo compilador não reconhece "array de inteiros" e "TIntArray" como tipos idênticos.

Então, aqui está a minha pergunta: Existe alguma maneira eu posso obter o compilador para identificar o meu parâmetro var como uma matriz dinâmica em vez de como uma matriz aberta para que o chamador pode declarar um simples "array de inteiros" em vez de algum chamado digite?

Agradecemos antecipadamente.

Foi útil?

Solução

Pascal, e por extensão Delphi, usa equivalência nome em vez de equivalência estrutural para tipos de matriz, incluindo matrizes dinâmicas. Variáveis ??declaradas com um tipo que não tem um nome, como este:

var
  x: array of Integer;

... acabar com um nome anônimo que não é equivalente ao nome de qualquer outro tipo. É por isso que você recebe o erro. O erro pode ser útil; por exemplo, considerar uma série de Kilometers vs uma série de Kilograms - mas é frequentemente o caso que declarar um nome para cada tipo distinto é inconveniente

.

Para contornar este problema, e ficar dentro do sistema de tipo seguro (evitando assim parâmetros sem tipo, como skamradt sugere), eu recomendo usar o mesmo nome para cada forma de matriz específico. Você pode fazer isso a um razoavelmente grande grau usando o tipo de TArray<T> declarada na unidade do sistema. Assim, em vez de trabalhar com array of Integer, TArray<Integer> uso.

TArray<T> é declarada como este:

type
  TArray<T> = array of T;

... para que ele possa fornecer um nome para matrizes dinâmicas arbitrárias.

Outras dicas

Este é realmente possível ... é só usar a palavra-chave absoluto juntamente com um var sem tipo.

procedure SizeArray(var aArr; aSize: integer);
var
  ActArr : Array of Integer absolute aArr;
begin
  SetLength(ActArr,aSize);
end;

var
  Test : Array of Integer;
begin
  SizeArray(Test,5);
  showMessage(IntTostr(High(Test)));  // -- returns 4
end;

Não, não há nenhuma maneira de fazer isso. É parte da especificação de linguagem Pascal e não é susceptível de alteração.

EDIT: Skamradt encontrou uma maneira. Deixe-me reformular isso. Não há nenhuma maneira de fazer isso com segurança.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top