在程式設計語言中,名字綁定是把實體(數據或/且代碼)關聯到標識符。[1]標識符綁定到實體被稱為引用該對象。機器語言沒有內建的標識符表示方法,但程式語言實現了名字與對象的綁定。綁定最初是與作用域相關,因為作用域確定了哪個名字綁定到哪個對象——在程序代碼中的哪個位置與哪條執行路徑。
綁定時機
- 靜態綁定(Static binding)或稱早綁定(early binding):名字綁定發生在程序開始運行之前。[2]
- 動態綁定(Dynamic binding)或稱遲綁定(late binding)、虛綁定(virtual binding):名字綁定發生在程序運行時。[2]
靜態綁定的例子,如C語言的函數調用:用標識符引用的函數在運行時不能改變。
動態綁定的例子如C++虛函數調用時的動態分派。由於多態對象的具體類型在運行前是未知的,因此被執行函數需要動態綁定。
public void foo(java.util.List<String> list) {
list.add("bar");
}
List
是一個接口,因此list
必須引用到它的子類型。它是引用到LinkedList
,ArrayList
或List
的其它子類型?add
實際引用到的方法在運行時之前也是未知的。C語言中,這種動態綁定可以通過調用一個函數指針類型的變量或表達式,其值直到運行時求值之前都是未知的。
重綁定與變異
重綁定不能與變異混淆:
- 重綁定(Rebinding)是改變引用的標識符;
- 變異(Mutation)是改變被引用的實體。
考慮下面Java代碼:
LinkedList<String> list;
list = new LinkedList<String>();
list.add("foo");
list = null;
標識符list
最初引用到空(未初始化);然後重綁定到一個對象(一個字符串鍊表);這個被list
引用的字符串鍊表被變異,即增加一個字符串到該鍊表;最後,list
被重綁定到null
。
靜態遲綁定
靜態遲綁定(late static binding)是靜態綁定與動態綁定之間的一個變種。考慮下述PHP例子:
class A
{
static $word = "hello";
static function hello() { print self::$word; }
}
class B extends A
{
static $word = "bye";
}
B::hello();
在上例中,PHP解釋器把A::hello()
關鍵字self
綁定到類A
,因此B::hello()
打印出字符串"hello"。如果self::$word
的語義是基於靜態遲綁定,結果就是"bye"。
從PHP版本5.3開始支持靜態遲綁定。[3]具體說,上例中的self::$word
如果改為下例中的static::$word
,關鍵字static
指示運行時才綁定,B::hello()
的調用結果將是"bye":
class A
{
static $word = "hello";
static function hello() { print static::$word; }
}
class B extends A
{
static $word = "bye";
}
B::hello();
參見
- 遲綁定
- 分支表
- 動態分派
- 高階抽象語法 (HOAS)
參考文獻
Wikiwand in your browser!
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.