Saltar al contenido

¿Cómo asignar una función, devuelta por otra función, a una variable de función? El resultado en lugar de la función generadora en sí.

Basta ya de buscar por otros sitios porque estás al sitio correcto, contamos con la solución que quieres hallar pero sin problema.

Solución:

Si sus métodos/funciones anónimos no tienen parámetros, debe asignarlos con ();

v1 := GetHandler();

Sin los paréntesis, Delphi intentará asignar el función a la variable. Los padres le dicen que invoque la función y asigne el resultado de la función a la variable.

La sintaxis de llamada de función de Delphi es un poco diferente de la mayoría de los otros lenguajes. En la mayoría de los idiomas, para llamar a una función debe usar paréntesis () después del nombre de la función, comúnmente conocido como el operador de llamada de función. Si simplemente se nombra la función y no se proporcionan paréntesis, esa expresión se evalúa como la función sin invocar una llamada.

Entonces, con el lenguaje C++ como nuestro ejemplo,

i = foo();

llama a la función y almacena el valor de retorno en i.

Por otra parte,

fn = foo;

almacena la dirección de la función en la variable de puntero de función fn.

Delphi varía de esto, para una función sin parámetros, al permitirle omitir los paréntesis y aún así llamar a la función. Entonces, en Delphi, la primera línea de código anterior podría escribirse

i := foo;

y esto llamaría a la función.

Donde se complica un poco es si el tipo de devolución de la función es un tipo de procedimiento, un método o un método anónimo, como ha descubierto.

En tu escenario,

v1 := GetHandler;

es ambiguo a los ojos del compilador. Porque v1 es una variable cuyo tipo es un método anónimo, el compilador nunca generará una llamada cuando se omitan los paréntesis. Si generara una llamada, entonces no podría realizar la asignación simple de una función a una variable de tipo procedimental.

Entonces el compilador cambia al comportamiento que encuentras en lenguajes como C++. Debe proporcionar paréntesis si desea que se llame a la función. Para hacer que su código se compile y funcione, escriba

v1 := GetHandler();

La documentación cubre el problema con cierto detalle. los key el extracto es este:

En las sentencias de asignación, el tipo de la variable de la izquierda determina la interpretación de los punteros de procedimiento o método de la derecha.


Ahora, emitiendo un juicio, encuentro que la idea de que el contexto de una expresión puede determinar su interpretación es bastante inquietante. Todo esto se deriva de permitir que se realicen llamadas a funciones cuando se omiten los paréntesis. Preferiría tener que usar paréntesis siempre y así evitar las ambigüedades discutidas anteriormente. En particular, esto permitiría que el significado de la expresión sea independiente del contexto.

Para ver lo que quiero decir, volvamos a mi ejemplo original. Ahora seamos más específicos sobre los tipos involucrados:

type
  TIntFunc = function: Integer;

function foo: Integer;
begin
  Result := 42;
end;

var
  i: Integer;
  fn: TIntFunc;

En este punto podemos escribir:

i := foo;  // i is an integer, so the function is called
fn := foo; // fn is a procedural type variable, so the function is not called

Personalmente, considero que este estado de cosas no es del todo satisfactorio.

Reseñas y valoraciones del tutorial

Te invitamos a avalar nuestra función escribiendo un comentario y dejando una puntuación te lo agradecemos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada.