Uma construção mais comum em um Delphi aplicação seria uma procedimento ou função. Conhecidas como rotinas, procedimentos ou funções, são blocos de instrução que você chama de diferentes locais em um programa.
Simplesmente colocar um procedimento é uma rotina que não retorna um valor enquanto uma função retorna um valor.
Um valor de retorno de uma função é definido pelo tipo de retorno. Na maioria dos casos, você escreveria uma função para retornar um único valor que seria um número inteiro, string, booleano ou algum outro tipo simples, também os tipos de retorno podem ser uma matriz, uma lista de strings, uma instância de um objeto personalizado ou similar.
Observe que, mesmo que sua função retorne uma lista de cadeias (uma coleção de cordas) ainda retorna um único valor: uma instância da lista de cadeias.
Além disso, as rotinas Delphi podem realmente ter muitas faces: Rotina, Método, Ponteiro de método, Delegado de evento, Método anônimo ...
Uma função pode retornar vários valores?
A primeira resposta que vem à mente é não, simplesmente porque quando pensamos em uma função, pensamos em um único valor de retorno.
Certamente, a resposta para a pergunta acima é, no entanto, sim. Uma função pode retornar vários valores. Vamos ver como.
Parâmetros Var
Quantos valores a função a seguir pode retornar, um ou dois?
função PositiveReciprocal (const valueIn: inteiro; var valueOut: real): booleano;
A função obviamente retorna um valor booleano (verdadeiro ou falso). Que tal o segundo parâmetro "valueOut" declarado como um parâmetro "VAR" (variável)?
Parâmetros Var são passados para a função por referência significando que, se a função alterar o valor do parâmetro - uma variável no bloco de código de chamada -, a função alterará o valor da variável usada para o parâmetro.
Para ver como funciona acima, aqui está a implementação:
função PositiveReciprocal (const valueIn: inteiro; var valueOut: real): booleano;
início
resultado: = valueIn> 0;
E se resultado então valueOut: = 1 / valueIn;
fim;
O "valueIn" é passado como um parâmetro constante - a função não pode alterá-lo e é tratado como somente leitura.
Se "valueIn" ou maior que zero, o parâmetro "valueOut" recebe o valor recíproco de "valueIn" e o resultado da função é verdadeiro. Se valueIn for <= 0, a função retornará false e "valueOut" não será alterado de forma alguma.
Aqui está o uso:
var
b: booleano;
r: real;
início
r: = 5;
b: = PositiveReciprocal (1, r);
//here:
// b = verdadeiro (desde 1> = 0)
// r = 0,2 (1/5)
r: = 5;
b: = PositiveReciprocal (-1, r);
//here:
// b = false (desde -1
fim;
Portanto, o PositiveReciprocal realmente pode "retornar" 2 valores! Usando parâmetros var, é possível que uma rotina retorne mais de um valor.
Parâmetros de saída
Há outra maneira de especificar um parâmetro por referência - usando a palavra-chave "out", como em:
função PositiveReciprocalOut (const valueIn: inteiro; Fora valueOut: real): booleano;
início
resultado: = valueIn> 0;
E se resultado então valueOut: = 1 / valueIn;
fim;
A implementação do PositiveReciprocalOut é a mesma que do PositiveReciprocalOut, há apenas uma diferença: o "valueOut" é um parâmetro OUT.
Com os parâmetros declarados como "out", o valor inicial da variável referenciada "valueOut" é descartado.
Aqui está o uso e os resultados:
var
b: booleano;
r: real;
início
r: = 5;
b: = PositiveReciprocalOut (1, r);
//here:
// b = verdadeiro (desde 1> = 0)
// r = 0,2 (1/5)
r: = 5;
b: = PositiveReciprocalOut (-1, r);
//here:
// b = false (desde -1
fim;
Observe como na segunda chamada o valor da variável local "r" é definido como "0". O valor de "r" foi definido como 5 antes da chamada da função, mas desde que o parâmetro seja declarado como "out", quando "r" atingiu a função, o valor foi descartado e o valor "vazio" padrão foi definido para o parâmetro (0 para valores reais tipo).
Como resultado, você pode enviar com segurança variáveis não inicializadas para parâmetros externos - algo que você não deve fazer com os parâmetros "var". Os parâmetros são usados para enviar algo para a rotina, exceto aqui com parâmetros "out" :) e, portanto, variáveis não inicializadas (usadas para parâmetros VAR) podem ter valores estranhos.
Retornando registros?
As implementações acima, nas quais uma função retornaria mais de um valor, não são boas. A função realmente retorna um único valor, mas também retorna, melhor dizendo, altera os valores dos parâmetros var / out.
Por esse motivo, é muito raro você querer usar parâmetros de referência. Se forem necessários mais resultados de uma função, é possível que uma função retorne um tipo de registro variável.
Considere o seguinte:
tipo
TLatitudeLongitude = registro
Latitude: real;
Longitude: real;
fim;
e uma função hipotética:
função Onde estou(const townName: corda): TLatitudeLongitude;
A função WhereAmI retornaria o Latitude e longitude para uma determinada cidade (cidade, área, ...).
A implementação seria:
função Onde estou(const townName: corda): TLatitudeLongitude;
início// use algum serviço para localizar "townName" e atribua o resultado da função:
resultado. Latitude: = 45,54;
resultado. Longitude: = 18,71;
fim;
E aqui temos uma função retornando 2 valores reais. Ok, ele retorna 1 registro, mas esse registro possui 2 campos. Observe que você pode ter um registro muito complexo misturando vários tipos a serem retornados como resultado de uma função.
É isso aí. Portanto, sim, as funções Delphi podem retornar vários valores.