¿Hay una manera sencilla?Cómo emular a los cierres en c
Respuesta
Esa es una pregunta muy amplia. Fundamentalmente, un cierre es un puntero de instrucción junto con algún contexto almacenado que se requiere para ejecutar las instrucciones de la manera correcta. Ciertamente puedes juntar algo como esto en C usando estructuras y punteros de función.
Digamos que usted expresa un cierre que toma dos enteros y devuelve vacío como una estructura:
typedef struct VoidClosureIntInt {
void (*fn)(int, int);
int first;
int second;
} VoidClosureIntInt;
y supongamos que tiene una función:
void Foo(int x, int y);
Ahora, para crear un cierre que se invocar a Foo (23, 42), lo haría:
VoidClosureIntInt closure = {&Foo, 23, 42};
Y luego, para ejecutar más tarde ese cierre, lo haría hacer:
(*closure.fn)(closure.first, closure.second);
Una arruga más: la mayoría de las veces cuando se está utilizando cierres, que desea pasar contexto en torno allá de la vida del bloque de código en el que se crea el cierre. (Ejemplo: está pasando el cierre a una función que realiza algunas E/S asíncronas y eventualmente llamará a su cierre cuando termine la E/S). En tales casos, debe asegurarse de asignar su cierre en el montón, y eliminar su cierre cuando haya terminado con él. (Ver el ejemplo completo en la parte inferior).
Una nota final: obviamente hay una gran cantidad de máquinas aquí, y es sólo para un tipo de cierre (una función que toma dos argumentos enteros y devuelve void). Cuando he visto esto hecho en C, a menudo lo hace un generador de códigos que crea maquinaria para muchos tipos diferentes de cierres. También puede reducir la cantidad de texto repetitivo solo apoyando cierres que toman algunos (número fijo de) argumentos nulos * y luego encasilla dentro de las funciones que está utilizando para implementar esos cierres.
Si está en C++, puede aprovechar las funciones de idioma para hacer esto de manera mucho más genérica y con mucho menos tipeo. Ver Boost.Function para un ejemplo.
ejemplo completo:
#include <stdio.h>
#include <stdlib.h>
// Closure support.
typedef struct VoidClosureIntInt {
void (*fn)(int, int);
int first;
int second;
} VoidClosureIntInt;
// The returned closure should be run via RunAndDeleteClosure().
VoidClosureIntInt* NewClosure(void (*fn)(int, int), int first, int second) {
VoidClosureIntInt* closure = malloc(sizeof(*closure));
closure->fn = fn;
closure->first = first;
closure->second = second;
return closure;
}
void RunAndDeleteClosure(VoidClosureIntInt* closure) {
(*closure->fn)(closure->first, closure->second);
free(closure);
}
// Example use.
void Foo(int x, int y) {
printf("x=%d\ny=%d\n", x, y);
}
// We take memory ownership of closure.
void SomeAsynchronousFunction(VoidClosureIntInt* closure) {
RunAndDeleteClosure(closure);
}
int main(int argc, char** argv) {
VoidClosureIntInt* closure = NewClosure(&Foo, 23, 42);
SomeAsynchronousFunction(closure);
return 0;
}
Respuesta simple:
NO
En este momento, a menos que reducir esto a una especie de muy pequeño subconjunto de la funcionalidad de los cierres, que es como es.
supongo que depende de lo que su idea de "simple" es.
Existen varias implementaciones de esquema que están diseñados para integrarse como un lenguaje de extensión para los programas C. Enlace en un Esquema, escriba su cierre en Scheme, y listo.
- 1. ¿Tenemos cierres en C++?
- 2. ¿Cómo deben formatearse los cierres?
- 3. Cierres y Lambda en C#
- 4. Cómo emular C# as-operator en Java
- 5. ¿Cómo funcionan los cierres detrás de escena? (C#)
- 6. Cómo romper los cierres en JavaScript
- 7. ¿Cómo funcionan los cierres en Haskell?
- 8. ¿Cierres en los delegados del controlador de eventos C#?
- 9. Cómo emular los genéricos de tipo 'signo de interrogación (?)' En Java a C++?
- 10. Cierres en Scala vs Cierres en Java
- 11. Rubí bloques/cierres de Java en C
- 12. ¿Cómo puedo evitar los cierres de Javascript?
- 13. ¿Cómo se transforman los cierres Scala en objetos Java?
- 14. ¿Cómo se puede emular el espacio de nombres en C?
- 15. Cómo emular CUDA en Windows
- 16. Cómo emular la pereza
- 17. confundido por los cierres en JavaScript
- 18. ¿Cómo se relacionan los entornos, (en) cierres y marcos?
- 19. Android, ¿cómo emular los gestos de deslizamiento en AVD?
- 20. ¿Qué tiene de especial los cierres?
- 21. Cómo emular Event.timeStamp
- 22. C# SerialPort - emular el teclado pos
- 23. Cómo emular onLowMemory()?
- 24. Cierres en Java 7
- 25. ¿Cómo puedo emular punteros en Haskell?
- 26. ¿Cómo implementa Java los cierres de clase interna?
- 27. Cierres en Python
- 28. ¿Cómo implementar cierres sin gc?
- 29. Cierres en Ruby
- 30. Emular el envío dinámico en C++ en función de los parámetros de plantilla
Siempre pensó en cierres siendo un concepto atómica; ¿Cómo lo subconjiste? – Pierreten
Will Robinson parece tener un muy buen ejemplo de esto, por lo que esta respuesta es incorrecta. –
Robinson está mostrando un montón de código para implementar 'un pequeño (y no muy útil) subconjunto de cierres'. – bmargulies