Pregunta

¿Cómo puedo llamar a una función que debe ser llamado desde arriba de su creación?He leído algo acerca de las declaraciones forward, pero Google no está siendo útil en este caso.¿Cuál es la sintaxis correcta para esto?

¿Fue útil?

Solución

Lua es un lenguaje dinámico y las funciones son un tipo de valor que puede ser llamado con el () operador.Así que usted realmente no necesita para adelante declarar la función tanto como asegurarse de que la variable de alcance cuando la llamada es la variable con la que usted piensa que es.

Este no es un problema en absoluto para las variables globales que contienen funciones, ya que el medio ambiente global es el lugar predeterminado para buscar a resolver un nombre de variable.Para las funciones locales, sin embargo, usted necesita para asegurarse de que la variable local ya está en el ámbito en el léxico punto donde usted necesita llamar el valor que almacena, y también asegurarse de que en el tiempo de ejecución es realmente un valor que puede ser llamado.

Por ejemplo, aquí hay un par de condiciones mutuamente recursivas local funciones:

local a,b
a = function() return b() end
b = function() return a() end

Por supuesto, que también es un ejemplo del uso de la cola de llamadas para permitir la recursividad infinita que no hace nada, pero el punto aquí es el de las declaraciones.Al declarar las variables con local antes de que cualquiera tiene una función almacenada en él, esos nombres son conocidos por ser variables locales en el ámbito léxico de el resto de el ejemplo.A continuación, las dos funciones se almacenan, cada refiriéndose a la otra variable.

Otros consejos

Puede reenviar declarar una función al declarar su nombre antes de declarar el cuerpo de la función real:

local func1
local func2 = function()
  func1()
end
func1 = function()
  --do something
end

Sin embargo, las declaraciones hacia adelante solo son necesarias al declarar funciones con el alcance local.Eso es generalmente lo que quiere hacer, pero LUA también admite una sintaxis más como C, en cuyo caso la declaración a reenvío no es necesaria:

function func2()
  func1()
end
function func1()
  --do something
end

Pruebas bajo el LUA incrustado en Freeswitch, Declaración hacia adelante no funciona:

fmsg("CRIT", "It worked.")
function fmsg(infotype, msg)
   freeswitch.consoleLog(infotype,  msg .. "\n")
end

Resultado:

[error] mod_lua.cpp: 203 /usr/local/freeswitch/scripts/foo.lua:1: intento de llamar a Global 'FMSG' (un valor NIL)

Invirtiendo el orden (DUH) funciona.

Para comprender cómo la referencia adelantada en Lua trabaja en comparación con C, usted debe entender la diferencia fundamental entre C compilación y la Lua de ejecución.

  • En C, la referencia adelantada es un tiempo de compilación el mecanismo.Por lo tanto, si se incluyen una declaración forward plantilla en un módulo de C, entonces cualquiera de su código siguiente se empleará esta plantilla en la compilación de la llamada.Usted puede o no puede incluir la implementación de la función en el mismo módulo, en el que caso de que ambas declaraciones deben ser semánticamente idénticas o el compilador de error.Dado que este es un tiempo de compilación construir, el código compilado se puede ejecutar en cualquier orden.

  • En Lua, adelante de referencia es en tiempo de ejecución mecanismo en el que el compilado función genera un prototipo de función interna dentro del código, pero esto sólo es accesible como un tiempo de ejecución de Lua variable o valor después de la ejecución se transmiten a través de la declaración de la creación de un Lua cierre.Aquí el orden de declaración dentro de la fuente es inmaterial.Es el orden de ejecución que es importante:si el cierre no ha sido asociado a la variable, sin embargo, entonces la ejecución se lanzar un "valor nulo" excepción".
    Si usted está utilizando una variable local para mantener el valor de la función, entonces normal de ámbito local todavía se aplican normas:el local la declaración debe preceder su uso en la fuente y debe estar dentro del alcance, de lo contrario el compilador compila en el mal mundial o el exterior de la referencia local.Así que adelante de referencia utilizando los lugareños como se discutió en la otra respuesta va a trabajar, pero sólo si el Protos están vinculados a los cierres antes de la primera llamada se ejecuta.

no funciona para mí si intento llamar a la función antes de la definición.Estoy usando este script de LUA en NGINX CONF.

Hilo de entrada de LUA abortado: Error de tiempo de ejecución: LUA_REDIRECT.LUA: 109: Intento de llamar a Global 'Throworifany' (un valor NIL)

SNIPPET DE CÓDIGO -

...
throwErrorIfAny()
...

function throwErrorIfAny()
    ngx.say("request not allowed")
    ngx.exit(ngx.HTTP_OK)
end

Dadas algunas otras respuestas también han señalado que tampoco funcionó para ellos, es posible que la Declaración hacia adelante de LUA no funcione con otras herramientas.

PS: Funciona bien si pongo la definición de la función antes y luego llámela después de las salas.

Si usa OOP, puede llamar a cualquier miembro de la función antes de su "definición".

local myClass = {}
local myClass_mt = { __index = myClass }

local function f1 (self)

    print("f1")
    self:later() --not yet "delared" local function
end

local function f2 (self)

    print("f2")
    self:later() --not yet "declared" local function   
end
--...
--later in your source declare the "later" function:
local function later (self)

    print("later")   
end

function myClass.new()    -- constructor
    local this = {}

    this = {
        f1 = f1,
        f2 = f2,
        later = later,  --you can access the "later" function through "self"
    }

    setmetatable(this, myClass_mt)

    return this
end

local instance = myClass.new()

instance:f1()
instance:f2()

Salida del programa:

f1
later
f2
later

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top