回呼函式
外觀
回呼函式或簡稱回呼(callback),是電腦編程中對某一段可執行代碼的參照,它被作為參數傳遞給另一段代碼;預期這段代碼將回呼(執行)這個回呼函式作為自己工作的一部份。這種執行可以是即時的,如在同步回呼之中;也可以在後來的時間點上發生,如在非同步回呼之中。
程式語言以不同方式支援回呼,經常將它們實現為次常式、lambda表達式、塊或函式指標。
使用
[編輯]回呼的用途十分廣泛。例如,假設有一個函式,其功能為讀取設定檔並由檔案內容設定對應的選項。若這些選項由雜湊值所標記,則讓這個函式接受一個回呼會使得程式設計更加靈活:函式的呼叫者可以使用所希望的雜湊演算法,該演算法由一個將選項名轉變為雜湊值的回呼函式實現;因此,回呼允許函式呼叫者在執行時調整原始函式的行為。
回呼的另一種用途在於處理訊號或者類似物。例如一個POSIX程式可能在收到SIGTERM訊號時不願立即終止;為了保證一切執行良好,該程式可以將清理函式註冊為SIGTERM訊號對應的回呼。
回呼亦可以用於控制一個函式是否作為:Xlib允許自訂的謂詞用於決定程式是否希望處理特定的事件。
例子
[編輯]下列C語言代碼描述了利用回呼處理POSIX風格的訊號(在本範例中為SIGUSR1)的過程。值得注意的是,在處理訊號的過程中,呼叫printf(3)
是不安全的。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void sig(int signum)
{
printf("Received signal number %d!\n", signum);
}
int main(int argc, char *argv[])
{
signal(SIGUSR1, sig);
pause();
return 0;
}
系統呼叫pause(3)
會導致這個例子不做任何有意義的事,但這樣做可以給你充分的時間來給這個行程傳送訊號。(在類Unix系統上,可以呼叫kill -USR1 <pid>
,其中<pid>
代表該程式的行程號。執行之後,該程式應當會有反應。)
實現
[編輯]回呼的形式因程式設計語言而有差別。
- Objective-C中允許利用@selector關鍵字傳遞SEL類型的函式名。在實現中,SEL類型被定義為函式名字串。
- .NET語言中用到的事件與事件處理常式提供了用於回呼的通用語法。
- 在缺少函式類型的參數的物件導向的程式語言中,例如Java,回呼可以用傳遞抽象類或介面來類比。回呼的接收者會呼叫抽象類或介面的方法,這些方法由呼叫者提供實現。這樣的對象通常是一些回呼函式的集合,同時可能包含它所需要的資料。這種方法在實現某些設計模式時比較有用,例如訪問者模式,觀察者模式與策略模式。
參見
[編輯]參考資料
[編輯]- ^ Perl Cookbook - 11.4. Taking References to Functions. [2008-03-03]. (原始內容存檔於2008-04-10).
- ^ Advanced Perl Programming - 4.2 Using Subroutine References. [2008-03-03]. (原始內容存檔於2008-07-05).