Interesante

Cómo devolver múltiples valores de una función Delphi

Cómo devolver múltiples valores de una función Delphi

Una construcción más común en una aplicación Delphi sería un procedimiento o una función. Conocidos como rutinas, procedimientos o funciones, son bloques de instrucciones que usted llama desde diferentes ubicaciones en un programa.

En pocas palabras, un procedimiento es una rutina que no devuelve un valor, mientras que una función devuelve un valor.

El valor de retorno de una función se define por el tipo de retorno. En la mayoría de los casos, escribiría una función para devolver un solo valor eso sería un número entero, cadena, booleano o algún otro tipo simple, también los tipos de retorno podrían ser una matriz, una lista de cadenas, una instancia de un objeto personalizado o similar.

Tenga en cuenta que incluso si su función devuelve una lista de cadenas (una colección de cadenas), aún devuelve un único valor: una instancia de la lista de cadenas.

Además, las rutinas de Delphi realmente pueden tener muchas caras: rutina, método, puntero de método, delegado de eventos, método anónimo ...

¿Puede una función devolver valores múltiples?

La primera respuesta que viene a la mente es no, simplemente porque cuando pensamos en una función, pensamos en un solo valor de retorno.

Ciertamente, la respuesta a la pregunta anterior es, sin embargo, sí. Una función puede devolver varios valores. A ver cómo.

Parámetros Var

¿Cuántos valores puede devolver la siguiente función, uno o dos?

función Positivo Recíproco (const valueIn: entero; var valueOut: real): boolean;

La función obviamente devuelve un valor booleano (verdadero o falso). ¿Qué tal el segundo parámetro "valueOut" declarado como un parámetro "VAR" (variable)?

Parámetros var son pasados ​​a la función por referencia lo que significa que si la función cambia el valor del parámetro, una variable en el bloque de llamada del código, la función cambiará el valor de la variable utilizada para el parámetro.

Para ver cómo funciona lo anterior, aquí está la implementación:

función Positivo Recíproco (const valueIn: entero; var valueOut: real): boolean;

empezar

resultado: = valueIn> 0;

Si resultado luego valueOut: = 1 / valueIn;

fin;

El "valueIn" se pasa como una función de parámetro constante que no puede alterarlo, y se trata como de solo lectura.

Si "valueIn" o mayor que cero, al parámetro "valueOut" se le asigna el valor recíproco de "valueIn" y el resultado de la función es verdadero. Si valueIn es <= 0, la función devuelve false y "valueOut" no se modifica de ninguna manera.

Aquí está el uso:

var

b: booleano;

r: real;

empezar

r: = 5;

b: = positivo recíproco (1, r);

//aquí:

// b = verdadero (ya que 1> = 0)

// r = 0.2 (1/5)

r: = 5;

b: = positivo recíproco (-1, r);

//aquí:

// b = falso (desde -1

fin;

Por lo tanto, ¡PositiveReciprocal en realidad puede "devolver" 2 valores! Al usar los parámetros var, puede hacer que una rutina devuelva más de un valor.

Parámetros de salida

Hay otra forma de especificar un parámetro por referencia utilizando la palabra clave "out", como en:

función PositiveReciprocalOut (const valueIn: entero; fuera valueOut: real): boolean;

empezar

resultado: = valueIn> 0;

Si resultado luego valueOut: = 1 / valueIn;

fin;

La implementación de PositiveReciprocalOut es la misma que en PositiveReciprocal, solo hay una diferencia: el "valueOut" es un parámetro OUT.

Con los parámetros declarados como "out", el valor inicial de la variable referenciada "valueOut" se descarta.

Aquí está el uso y los resultados:

var

b: booleano;

r: real;

empezar

r: = 5;

b: = PositiveReciprocalOut (1, r);

//aquí:

// b = verdadero (ya que 1> = 0)

// r = 0.2 (1/5)

r: = 5;

b: = PositiveReciprocalOut (-1, r);

//aquí:

// b = falso (desde -1

fin;

Observe cómo en la segunda llamada el valor de la variable local "r" se establece en "0". El valor de "r" se estableció en 5 antes de la llamada a la función, pero dado que el parámetro se declaró como "out", cuando "r" alcanzó la función, el valor se descartó y el valor "vacío" predeterminado se estableció para el parámetro (0 para tipo real).

Como resultado, puede enviar de forma segura variables no inicializadas para los parámetros, algo que no debe hacer con los parámetros "var". Los parámetros se usan para enviar algo a la rutina, excepto aquí con los parámetros "out" :), y por lo tanto las variables no inicializadas (utilizadas para los parámetros VAR) podrían tener valores extraños.

Regresando Registros?

Las implementaciones anteriores donde una función devolvería más de un valor no son buenas. La función en realidad devuelve un solo valor, pero también devuelve, mejor decir altera, los valores de los parámetros var / out.

Debido a esto, es muy raro que desee utilizar parámetros por referencia. Si se requieren más resultados de una función, puede hacer que una función devuelva una variable de tipo de registro.

Considera lo siguiente:

tipo

TLatitudeLongitude = grabar

Latitud: real;

Longitud: real;

fin;

y una función hipotética:

función Dónde estoy(const nombre del pueblo : cuerda): TLatitudeLongitude;

La función WhereAmI devolvería la Latitud y Longitud para un pueblo determinado (ciudad, área, ...).

La implementación sería:

función Dónde estoy(const nombre del pueblo: cuerda): TLatitudeLongitude;

empezar// usa algún servicio para localizar "townName", luego asigna el resultado de la función:

result.Latitude: = 45.54;

result.Longitude: = 18.71;

fin;

Y aquí tenemos una función que devuelve 2 valores reales. Ok, devuelve 1 registro, pero este registro tiene 2 campos. Tenga en cuenta que puede tener un registro muy complejo que mezcla varios tipos para ser devueltos como resultado de una función.

Eso es. Por lo tanto, sí, las funciones de Delphi pueden devolver múltiples valores.