名字綁定

程式設計語言中,名字綁定是把實體(數據或/且代碼)關聯到標識符[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必須引用到它的子類型。它是引用到LinkedListArrayListList的其它子類型add實際引用到的方法在運行時之前也是未知的。C語言中,這種動態綁定可以通過調用一個函數指針類型的變量或表達式,其值直到運行時求值之前都是未知的。

重綁定與變異

重綁定不能與變異混淆:

  • 重綁定(Rebinding)是改變引用的標識符;
  • 變異(Mutation)是改變被引用的實體。

考慮下面Java代碼:

LinkedList<String> list;
list = new LinkedList<String>();
list.add("foo");
list = null;

標識符list最初引用到空(未初始化英語uninitialized variable);然後重綁定到一個對象(一個字符串鍊表);這個被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();

參見

參考文獻

  1. ^ Microsoft, Using early binding and late binding in Automation, Microsoft, May 11, 2007 [May 11, 2009], (原始內容存檔於2015-02-22) 
  2. ^ 2.0 2.1 Systems and software engineering — Vocabulary ISO/IEC/IEEE 24765:2010(E), IEEE, Dec 15, 2010 
  3. ^ Late Static Bindings. [July 3, 2013]. (原始內容存檔於2019-02-21).