2010-07-21 15 views
5

¿Qué es el cierre y su ejemplo de correspondencia?Definición de cierre y ejemplo

que tienen una gran cantidad de investigación y no podía entender. Explique en aspecto del concepto de lenguaje de programación genérico y aspecto del lenguaje de programación específico.

Por favor ayuda.

Gracias.

+0

Preguntas http://stackoverflow.com/questions/36636/what-is-a-closure y http://stackoverflow.com/questions/1095707/what-is-the-exact-definition-of-a- el cierre es similar a este –

Respuesta

1

Así es como pienso en un cierre ....

Un objeto función consiste en dos cosas. Lo primero es el código para la función, el segundo es el alcance en el que se ejecuta. En un cierre, el alcance en el que se ejecuta la función y el código están separados entre sí. El mismo código se puede ejecutar en una variedad de ámbitos.

Si esto se permite en una forma completamente restringido que daría lugar a una gran confusión. Incluso cuando se trata de algo tan flexible como el alcance dinámico (la función hereda el alcance del lugar desde donde se llamó) se vuelve muy confuso.

Los cierres son una forma conveniente de especificar reglas de ámbito que hacen mucho sentido, ya que sólo requieren la lectura del código en lugar de trazar la misma. En un cierre, la función obtiene el alcance de donde fue declarada.Si se declaró durante la ejecución de otra función, obtiene el alcance de esa instancia específica de la pila de la función. Esto es mucho más simple y fácil de entender que poder dar el cierre y el alcance arbitrario, o el alcance dinámico.

Aquí es un ejemplo de un cierre trivial en Python:

def outer(): 
    def closure(): 
     pass 
    return closure 

Aquí la función closure es un cierre. En realidad, no utiliza ninguna variable del ámbito en el que se definió, por lo que es bastante trivial, pero sigue siendo uno.

Aquí es un cierre no tan trivial, pero sigue siendo simple en Python:

def outer(x): 
     def closure(): 
      return x 
     return closure 
f1 = outer(5) 
f2 = outer(6) 

Calling f1() devolverá 5 y llamando f2() volverá 6. Como se puede ver, la función es closure código de pieza y alcance parcial

Cuando outer(5) se llama, se crea una entrada en la pila para la llamada que contiene una versión de la variable que contiene el valor x 5. A continuación, declara la función closure que recibe ese ámbito.

Cuando outer(6) se llama, se crea una entrada en la pila para la llamada que contiene una versión de la variable que contiene el valor x 6. A continuación, declara la función closure que recibe ese ámbito.

+0

Gracias por su explicación – peterwkc

9

Un cierre es básicamente una función B anidado dentro de una función A que se puede acceder a las variables locales de A:

function A() { 
    var x = 5; 

    function B() { 
     print(x); 
    } 

    return B; 
} 

Si usted viene de un fondo de C++, esto es bastante difícil de digerir. Cuando intentemos llamar a la función devuelta por A, ¿a qué se referirá x? ¿No será eso x inválido ya que A() terminó?

La respuesta es que en realidad vive en x. Que B volvimos realmente lleva x implícitamente. Genial, ¿eh?

En un sentido más general, un cierre es una función unida a algunos datos. En un lenguaje sin cierres como C, cada programa tiene un número fijo de funciones. Con cierres, puede, en cierto sentido, "crear funciones" vinculándolos con datos dinámicos. Por supuesto, nadie te impide emular cierres en C, pero a veces puede ser doloroso.

Los cierres son realmente útiles. Por ejemplo, supongamos que queremos aplicar nuestro propio "bucle":

function loop(count, f) { 
    for (var i = 0; i < count; i++) 
     f(i); 
} 

var array = [0,1,2,3,4]; 

loop(5, function(i) { 
    print(array[i]); 
}); 

que se le permita acceder a las variables externas sin hacer un montón de tonterías adicional mantiene buen código y sencilla. Sin cierres, es posible que tenga que pasar una variable de contexto a la función loop lugar:

function loop(count, f, ctx) { 
    for (var i = 0; i < count; i++) 
     f(i, ctx); 
} 

var array = [0,1,2,3,4]; 

loop(5, function(i, ctx) { 
    print(ctx[i]); 
}, array); 

Otro ejemplo: supongamos que queremos registrar una devolución de llamada en jQuery, pero puede ser ejecutado poco después de la función y su persona que llama y persona que llama de la persona que llama se termina la ejecución:

$(document).ready(function(){ 

    var clicked = 0; 

    $('#button').click(function(){ 
     clicked++; 
     alert("You've pressed the button " + clicked + " times."); 
    }); 

}); 

Si JavaScript fueron más como C++ (antes C++ 0x), que clicked variable se larga ido a la vez la función dada a $(document).ready() se llamaba, y el botón de clic la devolución de llamada tendría un comportamiento indefinido.

+0

Curiosamente C++ 0x ahora tiene lambdas que capturan variables de su alcance adjunto. Entonces, el argumento * "Si vienes de un fondo C++" * se vuelve menos relevante. –

+0

Eso es genial. Gracias. – LandonSchropp

+0

@Alexandre Jasmin: Es una forma de cierre muy extraña. Mucho más explícito que la mayoría de los idiomas que los respaldan. Aunque en realidad me gusta mucho mejor. Creo que debes _______ decir qué variables estás intentando usar del alcance adjunto. – Omnifarious

0

Si quieres un ejemplo de cierres le sugiero que para comprobar la libreta de

Inmersión en Python: Capítulo 6 - Los cierres & Generadores

El libro está abierto & gratis y puedes descargarlo en --->http://diveintopython3.org/

El ejemplo es interesante, clara y poco a poco toma un enfoque más avanzado. Para la primera exposición es genial, creo.

Tome una mirada en ella no hay ninguna razón para reproducirlo aquí tanto tiempo como usted puede simplemente descargarlo o leerlo en línea.

Cuestiones relacionadas