Callback (программирование)

Callback (англ. call — вызов, англ. back — обратный) или фу́нкция обра́тного вы́зова в программировании — передача исполняемого кода в качестве одного из параметров другому коду. Обратный вызов позволяет в функции исполнять код, который задаётся в аргументах при её вызове. Этот код может быть определён в других контекстах программного кода и быть недоступным для прямого вызова из этой функции. Некоторые алгоритмические задачи в качестве своих входных данных имеют не только числа или объекты, но и действия (алгоритмы), которые естественным образом задаются как обратные вызовы.

Применение

Концепция обратного вызова имеет много приложений. Например, некоторые алгоритмы (функции) в качестве подзадачи имеют задачу вычисления хеш-значения от строки. В аргументах при запуске алгоритма (функции) удобно задавать, какую именно функцию использовать для вычисления хеш-значений.

Другой пример алгоритма, которому естественно передавать в аргументе функцию, — алгоритм обхода какого-либо хранилища объектов с применением некоторого действия к каждому объекту. Обратный вызов может выступать в роли этого действия (алгоритма).

Техника программирования обратного вызова в языках программирования, подобных языку C, проста. При вызове основной функции ей просто передаётся указатель на функцию обратного вызова. Классическим примером является функция qsort из библиотеки stdlib. Эта функция позволяет отсортировать массив элементов одинаковой длины. В качестве аргументов она получает адрес первого элемента массива, количество элементов в массиве, размер элемента, и указатель на функцию сравнения двух элементов массива. Эта функция сравнения и есть функция обратного вызова в данном примере:

#include <stdlib.h>
// функция сравнения целых чисел по модулю
int compare_abs(const void *a, const void *b) {
   int a1 = *(int*)a;
   int b1 = *(int*)b;
   return abs(a1) - abs(b1);
}
int main() {
   int size = 10;
   int m[size] = {1, -3, 5, -100, 7, 33, 44, 67, -4, 0};
   // сортировка массива m по возрастанию модулей
   qsort(m, size, sizeof(int), compare_abs);
   return 0;
}

Об обратном вызове можно думать как о действии, передаваемом некоторой основной процедуре в качестве аргумента. И это действие может рассматриваться как:

  • подзадача и использоваться для обработки данных внутри этой процедуры;
  • «телефонная связь», используемая для того, чтобы «связываться» с тем, кто вызвал процедуру, при наступлении какого-то события (англ. callback дословно переводится как «звонок обратно»).

Показанный выше пример как раз соответствует первому случаю. Случай, когда обратный вызов используется как «телефонная связь», отражает код, где задаётся функция обработки определённого сигнала:

#include <stdio.h>
#include <signal.h>

volatile sig_atomic_t br = 1;

void sig(int signum)
{
        br=0;
}

int main(int argc, char *argv[])
{
        signal(SIGINT, sig);

        printf("Press break keyboard key combination to stop the program\n");

        while(br);
        
        printf("Received SIGINT, exit\n");

        return 0;
}

В некоторых языках программирования, таких как Common Lisp, Erlang, Scheme, Clojure, PHP, JavaScript, Perl, Python, Ruby и других, есть возможность конструировать анонимные (не именованные) функции и функции-замыкания прямо в выражении вызова основной функции, и эта возможность широко используется.

В технологии AJAX при выполнении асинхронного запроса к серверу необходимо указывать функцию обратного вызова, которая будет вызвана, как только придёт ответ на запрос. Часто эту функцию определяют «прямо на месте», не давая ей никакого определённого имени:

 new Ajax.Request('http://example.com/do_it',
 {
   method: 'post',
   onSuccess: function(transport) { // функция, вызываемая
      window.alert("Done!");        // при успешном выполнении запроса
   },                               // 

   onFailure: function() {          // функция, вызываемая
      window.alert("Error!");       // при ошибке выполнения запроса
   }
 });

Функция обратного вызова используется также в шаблоне проектирования «Наблюдатель» (Observer). Так, например, используя библиотеку Prototype, можно создать «наблюдателя», который следит за нажатиями на элемент с идентификатором "my_button" и при получении события пишет сообщение внутрь элемента "message_box":

 Event.observe ($("my_button"), 'click', function() {
   $("message_box").innerHTML = "Вы нажали на кнопку!"
 });

Функция обратного вызова является альтернативой полиморфизму функций, а именно, позволяет создавать функции более общего назначения вместо того, чтобы создавать серию функций, одинаковых по структуре, но отличающихся лишь в отдельных местах исполняемыми подзадачами. Функции, принимающие в качестве аргументов другие функции или возвращающие функции в качестве результата, называют функциями высшего порядка. Техника обратного вызова играет важную роль для достижения повторного использования кода.

Зачем использовать функции обратного вызова

Для лучшего понимания причин использования обратного вызова рассмотрим простую задачу выполнения следующих операций над списком чисел: напечатать все числа, возвести все числа в квадрат, увеличить все числа на 1, обнулить все элементы. Ясно, что алгоритмы выполнения этих четырёх операций схожи — это цикл обхода всех элементов списка с некоторым действием в теле цикла, применяемый к каждому элементу. Это несложный код, и в принципе можно написать его 4 раза. Но давайте рассмотрим более сложный случай, когда список у нас хранится не в памяти, а на диске, и со списком могут работать несколько процессов одновременно и необходимо решать проблемы синхронизации доступа к элементам (несколько процессов могут выполнять разные задачи — удаления некоторых элементов из списка, добавления новых, изменение существующих элементов в списке). В этом случае задача обхода всех элементов списка будет довольно сложным кодом, который не хотелось бы копировать несколько раз. Правильнее создать функцию общего назначения для обхода элементов списка и дать возможность программистам абстрагироваться от того, как именно устроен алгоритм обхода и писать лишь функцию обратного вызова для обработки отдельного элемента списка.

Структурирование ПО

Структурирование программного обеспечения через функции обратного вызова — очень удобный и широко используемый подход, так как при этом поведение программы с неизменным (в том числе закрытым) кодом можно изменять в очень широких пределах. Это реализуется двумя путями — или «альтернативной реализацией» какой-либо функции, или «добавлением в цепочку вызовов» ещё одной функции.

Как правило, разработчик реализует через обратные вызовы не всю функциональность программы, а лишь ту, которую предполагается расширять или изменять плагинами. Для подключения плагинов предоставляется специальная процедура, которая и заменяет «стандартные» обратные функции от разработчика на альтернативные из плагина.

Самым известным примером такого подхода является операционная система Microsoft Windows, где функции обратного вызова именуются «handler» («обработчик»), и существует возможность вставить дополнительную процедуру между любыми двумя стандартными. Этот подход называется «перехват событий» и используется, например: антивирусами для проверки файлов, к которым производится обращение; вирусами для считывания вводимых с клавиатуры символов; сетевыми фильтрами для сбора статистики и блокирования пакетов.

В современных Unix и Linux системах существует возможность динамической загрузки и выгрузки модулей ядра, работа которых также основана на функциях обратного вызова. При этом существует модуль (расширение ядра) FUSE, который, в свою очередь, предоставляет возможность обычным пользовательским программам обслуживать (перехватывать) запросы к виртуальным файловым системам.

В программном обеспечении иногда встречается декомпозиция программ, полностью основанная на функциях обратного вызова, что несколько ухудшает читаемость кода, но даёт максимальные возможности для плагинов. Пример такого продукта — DokuWiki.

Достоинства и недостатки

Достоинства:

  • Возможность динамического изменения функциональности (подключения и отключения плагинов/модулей при работе программы).
  • Возможность неограниченного количества вариантов вызываемой функции без изменения базового (в данном контексте) кода.
  • Возможность вставки вызываемой функции не только для альтернативного поведения, но и в качестве ещё одной (промежуточной) подпрограммы — обычно для отслеживания операций или изменения параметров для следующей (вызываемой) функции. Таких независимых «дополнительных звеньев» в цепочке вызовов может быть сколько угодно.
  • Поддержка функций обратного вызова в большинстве современных языков программирования общего назначения.

Недостатки:

  • Уменьшение производительности, связанной с дополнительными вызовами «обратной функции», прямо пропорционально «стоимости вызова функции» в среде выполнения и количеству дополнительных вызовов при работе программы.
  • Ухудшение читаемости исходного кода — для понимания алгоритма программы необходимо отслеживать всю цепочку вызовов.

См. также

Ссылки

Read other articles:

Dentin adalah zat antara email (zat di mahkota) atau semen (zat di akar) dari gigi dan ruang pulpa. Dentin disekresikan oleh odontoblast pulpa gigi. Pembentukan dentin dikenal sebagai dentinogenesis. Yang menyerap, bahan warna kuning tersusun atas 70% bahan anorganik, 20% bahan organik, dan 10% air.[1] Karena lebih lembut daripada email, dentin membusuk lebih cepat dan menjadi sasaran lubang hebat jika tak dirawat sebagaimana mestinya. Namun tetap berlaku sebagai lapisan protektif da...

 

Politeknik Teknologi Kimia Industri MedanDidirikan1983AlamatJalan Medan Tenggara No. VII, Medan, Sumatera Utara, IndonesiaSitus webptki.ac.id Politeknik Teknologi Kimia Industri atau disingkat PTKI Medan adalah salah satu Perguruan Tinggi Milik Pemerintah di bawah naungan Kementerian Perindustrian Republik Indonesia. PTKI Medan didirikan pada tahun 1983 dengan bantuan Grant Aids dari Pemerintah Jepang (JICA) dengan areal seluas kurang lebih 8 Ha. Sejarah Program Studi Diploma III (D3) Agribis...

 

Protected wilderness area in California, United States San Rafael WildernessIUCN category Ib (wilderness area)Location of the San Rafael Wilderness in Santa Barbara County, CaliforniaLocationSanta Barbara County, California, United StatesNearest citySanta Barbara, CaliforniaCoordinates34°48′41″N 119°51′46″W / 34.81139°N 119.86278°W / 34.81139; -119.86278Area197,380 acres (799 km2)Established1968Governing bodyU.S. Forest Service San Rafael Wilderne...

Region of France For other uses, see Alsace (disambiguation). Elsaß redirects here. For the battleship, see SMS Elsaß. For the region of the German Empire, see Alsace-Lorraine. This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Alsace – news · newspapers · books · scholar · JSTOR (August 2022) (Learn how and ...

 

County in South Hwanghae Province, North KoreaKangryŏng County 강령군CountyKorean transcription(s) • Hanja康翎郡 • McCune-ReischauerKangryŏng-gun • Revised RomanizationGangryeong-gunCountryNorth KoreaProvinceSouth Hwanghae ProvinceAdministrative divisions1 ŭp, 31 riArea • Total522.7 km2 (201.8 sq mi)Population (2008[1]) • Total106,827 • Density200/km2 (530/sq mi) This article...

 

Tullio Scanferlini Nazionalità  Italia Altezza 171 cm Peso 72 kg Calcio Ruolo Centrocampista Termine carriera 1941 Carriera Squadre di club1 1931-1933 Dolo? (?)1933-1934 Milan2 (0)1934-1935 Cremonese18 (0)1935-1936 Milan0 (0)1936-1941 Cremonese56 (2) 1 I due numeri indicano le presenze e le reti segnate, per le sole partite di campionato.Il simbolo → indica un trasferimento in prestito.   Modifica dati su Wikidata · Manuale Tullio Giovanni Scanferl...

early morning walks in Kaggadasapura be like This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Kaggadasapura – news · newspapers · books · scholar · JSTOR (July 2019) (Learn how and when to remove this template message) 12°58′45.7″N 77°40′25.4″E / 12.979361°N 77.673722°E / 1...

 

King of Elam Untash-NapirishaKing of ElamStatue of Napir-Asu, wife of Untash-Napirisha in Louvre Museum Inscription: I, Napir-Asu, wife of Untash-Napirisha. He who would seize my statue, who would smash it, who would destroy its inscription, who would erase my name, may he be smitten by the curse of Napirisha, of Kiririsha, and of Inshushinka, that his name shall become extinct, that his offspring be barren, that the forces of Beltiya, the great goddess, shall sweep down on him. This is Napi...

 

François IIPotret oleh François ClouetRaja PrancisBerkuasa10 July 1559 – 5 December 1560Penobatan21 September 1559PendahuluHenri IIPenerusCharles IXRaja permaisuri SkotlandiaTenure24 April 1558 – 5 December 1560Informasi pribadiKelahiran(1544-01-19)19 Januari 1544Château de Fontainebleau, PrancisKematian5 Desember 1560(1560-12-05) (umur 16)Orléans, PrancisPemakaman23 Desember 1560Basilique royale de Saint-Denis, PrancisWangsaValois-AngoulêmeAyahHenri IIIbuCatherine de' MediciPas...

† Человек прямоходящий Научная классификация Домен:ЭукариотыЦарство:ЖивотныеПодцарство:ЭуметазоиБез ранга:Двусторонне-симметричныеБез ранга:ВторичноротыеТип:ХордовыеПодтип:ПозвоночныеИнфратип:ЧелюстноротыеНадкласс:ЧетвероногиеКлада:АмниотыКлада:Синапсиды�...

 

LA-3 redirects here. For the state highway, see Louisiana Highway 3.U.S. House district for Louisiana Louisiana's 3rd congressional district From 2023 to 2025 From 2025Interactive map of district boundariesRepresentative  Clay HigginsR–LafayetteDistribution73.4% urban[1]26.6% ruralPopulation (2022)760,945[2]Median householdincome$53,406[2]Ethnicity64.4% White24.6% Black5.3% Hispanic3.2% Two or more races1.7% Asian0.8% otherCook PVIR+21[3] Louisiana's 3rd...

 

Peta menunjukkan lokasi Talacogon. Talacogon adalah munisipalitas yang terletak di provinsi Agusan del Sur, Filipina. Pada tahun 2011, munisipalitas ini memiliki penduduk sebesar 45.233 jiwa atau 6.521 rumah tangga.[1] Pembagian wilayah Secara administratif Talacogon terbagi menjadi 16 barangay, yaitu: Batucan Buena Gracia Causwagan Culi Del Monte Desamparados La Flora Labnig Maharlika Marbon Sabang Gibung San Agustin (Pob.) San Isidro (Pob.) San Nicolas (Pob.) Zamora Zillovia Referen...

Neighborhood of Philadelphia in Pennsylvania, United StatesEast Passyunk CrossingNeighborhood of PhiladelphiaGateway Plaza East Passyunk Welcome SignEast Passyunk CrossingCoordinates: 39°55′35″N 75°09′48″W / 39.9265°N 75.1633°W / 39.9265; -75.1633Country United StatesStatePennsylvaniaCountyPhiladelphiaCityPhiladelphiaZIP code19148Area code(s)215, 267, and 445 East Passyunk Crossing is a neighborhood in South Philadelphia, Pennsylvania, United States. I...

 

Protein domain PAS foldCrystallographic structure of the PAS domain of the bacterial oxygen sensor protein fixL.[1] The protein is depicted as a rainbow colored cartoon (N-terminus = blue, C-terminus = red) while the heme ligand is shown as sticks (carbon = white, nitrogen = blue, oxygen = red, iron = orange).IdentifiersSymbolPASPfamPF00989InterProIPR013767SMARTPASPROSITEPDOC50112SCOP22phy / SCOPe / SUPFAMCDDcd00130Available protein structures:Pfam  structures / ECOD  PDBRCS...

 

此條目可参照外語維基百科相應條目来扩充。若您熟悉来源语言和主题,请协助参考外语维基百科扩充条目。请勿直接提交机械翻译,也不要翻译不可靠、低品质内容。依版权协议,译文需在编辑摘要注明来源,或于讨论页顶部标记{{Translated page}}标签。 Osagyefo克瓦米·恩克鲁玛第三届非洲联盟主席任期1965年10月21日—1966年2月24日前任贾迈勒·阿卜杜-纳赛尔继任约瑟夫·亚瑟·�...

Chronologies Données clés 1869 1870 1871  1872  1873 1874 1875Décennies :1840 1850 1860  1870  1880 1890 1900Siècles :XVIIe XVIIIe  XIXe  XXe XXIeMillénaires :-Ier Ier  IIe  IIIe Chronologies géographiques Afrique Afrique du Sud, Algérie, Angola, Bénin, Botswana, Burkina Faso, Burundi, Cameroun, Cap-Vert, République centrafricaine, Comores, République du Congo, République démocratique du Congo, Côte d'Ivoire, Djibouti, Égyp...

 

This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Star Wars: X-Wing vs. TIE Fighter – news · newspapers · books · scholar · JSTOR (November 2007) (Learn how and when to remove this message) 1997 video gameStar Wars: X-Wing vs. TIE FighterDeveloper(s)Totally GamesPublisher(s)LucasArtsDesigner(s)Lawrence Hollan...

 

NH bypass in Kerala Kollam Bypassകൊല്ലം ബൈപ്പാസ്Kadavoor bridge: Part of Kollam BypassRoute informationMaintained by NHAILength13.141 km (8.165 mi)StatusOperationalHistory2019-Present Timeline Planned : 1972Approval : 1978Phase-I : 1993Phase-II : 1999Phase-III : 2019 Major junctionsSouth end NH-66 in MevaramMajor intersectionsKollam-Kulathupuzha road in Ayathil NH-744 in Kallumthazham NH-183 in KadavoorKureepuzha road in...

اضغط هنا للاطلاع على كيفية قراءة التصنيف طرخشقون نبات الطرخشقون المخزني المرتبة التصنيفية جنس  التصنيف العلمي النطاق: حقيقيات النوى المملكة: النباتات الفرقة العليا: النباتات الأرضية القسم: النباتات الوعائية الشعبة: مستورات البذور الطائفة: ثنائيات الفلقة الرتبة: نجميا...

 

Cultural and population changes in England c. 450 to 630 AD This article is part of the series:Anglo-Saxonsociety and culture People Settlement Women History Language Language Literature Runes Material culture Architecture Art Burial Coins Dress Glass Weaponry Power and organization Charters Government Law Monarchs and kingdoms Warfare Military Religion Christianity Paganism vte This article is about Anglo-Saxon settlement in Britain. For later historical events in Anglo-Saxon England, see Hi...