Node:Замыкание и обратный вызов,
Next:Объектная ориентация и замыкание,
Previous:Общая переменная,
Up:О замыкании
[Показать/скрыть оригинал] [Показать/скрыть перевод] [Переключить перевод и оригинал]
A frequently used programming model for library code is to allow an application to register a callback function for the library to call when some particular event occurs. It is often useful for the application to make several such registrations using the same callback function, for example if several similar library events can be handled using the same application code, but the need then arises to distinguish the callback function calls that are associated with one callback registration from those that are associated with different callback registrations.
В программировании часто используется метод, в котором библиотека позволяет указать приложению функцию, вызываемую по какому-либо событию (event). Часто бывает полезно указать одну функцию для нескольких событий (несколько схожих событий могут быть обработаны одним и тем же кодом). Но возникает задача различить внутри вызванной функции, какой именно вызов был произведён (какое именно событие из тех, которые вызывают процедуру, наступило).
In languages without the ability to create functions dynamically, this
problem is usually solved by passing a user_data parameter on the
registration call, and including the value of this parameter as one of
the parameters on the callback function. Here is an example of
declarations using this solution in C:
В языках без возможности динамически создавать функции, эта проблема
обычно решается передачей параметра user_data в регистрационный вызов, и передачей
значения этого параметра как одного из параметров вызываемой функции. Вот пример декларации
фунции на С, использующей этот приём:
typedef void (event_handler_t) (int event_type,
void *user_data);
void register_callback (int event_type,
event_handler_t *handler,
void *user_data);
In Scheme, closure can be used to achieve the same functionality without
requiring the library code to store a user-data for each callback
registration.
В Scheme, замыкание может быть использовано для достижения подобной
функциональности без необходимости сохранения user-data внутри библиотеки
для каждого вызова.
;; In the library:
(define (register-callback event-type handler-proc)
...)
;; In the application:
(define (make-handler event-type user-data)
(lambda ()
...
<code referencing event-type and user-data>
...))
(register-callback event-type
(make-handler event-type ...))
As far as the library is concerned, handler-proc is a procedure
with no arguments, and all the library has to do is call it when the
appropriate event occurs. From the application's point of view, though,
the handler procedure has used closure to capture an environment that
includes all the context that the handler code needs --
event-type and user-data -- to handle the event
correctly.
С точки зрения библиотеки, handler-proc - процедура
без аргументов, и всё, что остаётся делать библиотеке - вызывать её, когда происходит
событие. С точки же зрения приложения, обрабатывающая процедура использует замыкание для
захвата окружения, включающего в себя контекст, необходимый процедуре для правильной
обработки каждого события - event-type и user-data.
> > далее > >