Reddit был первоначально записан в Lisp и затем позже переписан в Python. Существует хороший анализ переключателя и что это означает для Lisp в Lisp Открытия.
Я знаком с некоторыми Java и C #
Обратный вызов - это событие или делегат на этих языках - способ заставить ваш код запускаться другим кодом в это контекст. Отсюда и термин «обратный вызов»:
Каноническим примером является процедура сортировки с определяемой пользователем функцией сравнения (обратный вызов). Для такой процедуры сортировки, как:
void Sort(void* values, int length, int valueSize,
int (*compare)(const void*, const void*)
{
for (int i = 0; i < length; i = i + 2) {
// call the callback to determine order
int isHigher = compare(values[i], values[i + 1]);
/* Sort */
}
}
(Специфика того, как выполняется сортировка, не важна - просто сосредоточьтесь на том факте, что любой алгоритм сортировки должен сравнить 2 значения и определить, какое из них выше. )
Итак, теперь мы можем определить некоторые функции сравнения:
int CompareInts(const void* o, const void* p) {
int* a = (int*) o;
int* b = (int*) p;
if (a == b) return 0;
return (a < b) ? -1 : 1;
}
int ComparePersons(const void* o, const void* p) {
Person* a = (Person*) o;
Person* b = (Person*) p;
if (a == b) return 0;
return (a->Value() < b=>Value()) ? -1 : 1;
}
И повторно использовать с ними ту же функцию сортировки:
int intValues[10];
Person personValues[10];
Sort(intValues, 10, sizeof(intVaues[0]), CompareInts);
Sort(personValues, 10, sizeof(personVaues[0]), ComparePersons);
Все становится немного сложнее, если вы используете функции-члены, поскольку вам нужно управлять this
указатель - но концепция та же. Как и большинство вещей, их проще сначала объяснить на C. ;)
Когда вы отправляете что-то обратный вызов, вы отправляете ему способ адресации функции (например, указателя функции в C ++), чтобы код, который вы отправляете он может вызвать эту функцию позже, когда она завершит какой-либо процесс.
Разница между
start_some_process(some_value, some_function()) # not using a callback
и
start_some_process(some_value, some_function) # using a callback
заключается в том, что в первом случае вы отправляете результат функции, а во втором случае вы отправляете саму функцию .
Обратный вызов - это перехватчик кода, который выполняется, чтобы позволить вам предоставлять настраиваемые функции в известных точках процесса. Это позволяет обобщенным структурам управления выполнять настраиваемые операции, которые определяются вашим кодом, который вызывается из них, отсюда и термин «обратный вызов» - он вызывает обратный вызов в ваш код.
Обычно это делается путем предоставления указателя на функцию с определенной заранее определенной сигнатурой, а общий код, выполняющий обратный вызов, будет передавать параметры вашей функции и ожидайте возвращаемое значение определенного типа.
Это действительно мощный шаблон, который позволяет повторно использовать код и довольно простую настройку / расширение без полного переписывания.
Пользовательские функции сортировки - отличный пример. Алгоритм сортировки является общим, функция сравнения зависит от того, что сортируется. Многие алгоритмы позволяют вам предоставить функцию, которая принимает два аргумента универсальных типов, являющихся объектами для сравнения, и ожидает, что вы вернете значение + ve, -ve или ноль в зависимости от результата сравнения.
Проще говоря, обратный вызов - это код, который вы передаете другому методу.
Например, у вас есть класс A, который вызывает метод класса B, но вам нужны некоторые код, запущенный из класса A, когда он закончен. Вы помещаете свой код в отдельный новый метод класса A и передаете имя метода, когда вызываете метод класса B. Когда метод класса B выполнил свою работу, он может «вернуться» в класс A.
В настоящее время вы не На самом деле нужно поместить код обратного вызова в отдельный метод: у вас есть анонимные методы и лямбда-выражения, которые вы можете использовать. Я думаю, что, вероятно, наименее запутанно (по крайней мере, в C #) учиться использовать анонимные методы, пока вы этого не получите.
Удачи!
PS Я был таким же: я кодировал C # в течение многих лет, прежде чем я действительно их понял.