¿Cómo 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?

6 Comentarios

  1. 33

    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

    De curso, que es también 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.

    • Muy bien, gracias. Me las arreglé para averiguar por mi cuenta, pero esta respuesta fue útil, no obstante.
  2. 11

    Puede reenviar declarar una función por la que se declare su nombre antes de declarar el real cuerpo de la función:

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

    Sin embargo declaraciones forward sólo son necesarios cuando se declaran las funciones con las de ámbito local. Que generalmente es lo que quieres hacer, pero Lua también soporta una sintaxis más parecido a C, en cuyo caso la declaración forward no es necesario:

    function func2()
      func1()
    end
    function func1()
      --do something
    end
    • En realidad, el primer ejemplo no es lo que piensa desde la segunda local func1 es la declaración de una nuevo variable de ese nombre y deja la primera func1 huérfanos y aún nil.
    • uy buen punto, voy a arreglar eso
    • El segundo ejemplo es malo, también, porque ingenuamente llamar «func2» desde abajo func1 iba a funcionar, pero no a causa de ningún tipo de «declaración forward». Más bien, func1 se declara en el medio ambiente mundial (_G), y cuando func2 busca func1, comprueba _G. Eso significa que func1 se declara antes de func2 se ejecuta y por lo tanto cuando se comprueba _G, funciona. Lanzar una func2 llame inmediatamente después de func2 es de los resultados definidos en un error… porque func1 no declarado/definido.
    • Por eso dije «sin Embargo declaraciones forward sólo son necesarios cuando se declaran las funciones con las de ámbito local». En otras palabras, estaba diciendo explícitamente el segundo ejemplo no utiliza adelante declaración.
  3. 1

    Pruebas bajo el incrustados lua en Freeswitch, adelante declaración no funciona:

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

    resultado:

    [ERR] mod_lua.cpp:203 /usr/local/freeswitch/scripts/foo.lua:1: intento de llamar a global ‘fmsg’ (un valor nil)

    Invertir el orden no (duh) de trabajo.

  4. 1

    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, adelante de referencia es un tiempo de compilación 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, la referencia adelantada es 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: la local 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.

  5. 0

    No me funciona si intento llamar a la función antes de la definición. Estoy usando este Lua script en nginx conf.

    lua entrada hilo abortado: error de tiempo de ejecución: lua_redirect.lua:109: intento de llamar a global ‘throwErrorIfAny’ (un valor nil)

    Fragmento de código –

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

    Dado algunas otras respuestas también han señalado que no trabajo para ellos, es posible que se adelante la declaración de Lua no trabajar con otras herramientas.

    PS : funciona bien si pongo la definición de la función antes y, a continuación, llamar después de las salas.

  6. 0

    Si utiliza la programación orientada a objetos se puede llamar a cualquier función miembro 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()

    La salida del programa:

    f1
    later
    f2
    later

Dejar respuesta

Please enter your comment!
Please enter your name here