Type System

Type System 往往是設計新程式語言時,最先考量的一個重要關鍵。
以下就來針對一般常見四種 Type System 用簡單的範例來介紹,避免混淆:

  1. Static Typing
  2. Dynamic Typing
  3. Structual Typing
  4. Duck Typing

Static Typing

使用 Static Typing 的語言中,最常見的自然就是大家所知的 C/C++ ,也就是所有的型態都是靜態宣告,而且要明確的指出每個變數的型態,程式範例如下:

void foo() { int a =1; int b =2; int c = a + b; }

Dynamic Typing

而對於 Dynamic Typing 而言,最廣為人知的就是 Script Language ,像我以下舉的 Python 範例即是。主要的精神為型態不必預先宣告,而是在執行時期自動以該變數內含值來判斷該變數所對應的形態,範例如下:

def foo(): c = '3' a = 1 b = 1 c = a + b # 最後 c 的型態依舊為整數

剩下這兩個 Type System 就比較沒有這麼直覺的,而且比較容易混淆。

Duck Typing

兩個變數在運算時,不論任何 Type System 都需要知道這兩個變數的型態,才可以做對應的運算。而在 Duck Typing 中,它不在乎這兩個型態是否完全相同,但它要求針對某個任務而言,這兩個變數的型態是不是都具有相對應的功能,如果有,就視為相同的(簡單一句話: If it just fits, it’s OK. ),範例如下:

class bird: def quack(self): print "quack!" def swim(self): print "swim!" def fly(self): print "fly!" class duck: def quack(self): print "quack!" def swim(self): print "swim!" def action(duck): duck.quack() duck.swim() animal_bird = bird() action(animal_bird)

由這個例子可以很明顯的看出,即使傳入的物件型態不是 Duck ,但是因為他有 Duck 所具有的功能,所以就當它是 Duck。
為什麼要以鴨子為例呢?源自於此:

印第安納詩人詹姆斯‧惠特科姆‧萊利: 「當我看到一隻鳥,它走路像鴨子,游泳像鴨子,叫聲像鴨子,我就稱其為鴨子。」

Structural Typing

瞭解了 Duck Typing 之後,就可以比較瞭解 Structural Typing 了。差異就是 Duck Typing 只要求要執行的功能你有,那就讓你執行,但是 Structural Typing 則要求兩個變數結構上的功能都要完全一樣才可以,所以再看一次上述的例子:如果 Python 改為 Structural Typing 的語言,那麼在編譯的時候就會發生型態不符的錯誤,因為 Bird 多出了 fly()。

簡單的說,Structural Typing 就是比較嚴謹的 Duck Typing 而已,至於到底該採用哪種,則是依設計理念來衡量,如果是希望避免無謂的錯誤,那可能就會選擇 Structural Typing;反之,如果求開發速度,那就會選 Duck Typing。由於採用 Structural Typing 的語言相對比較沒這麼熱門,有興趣的可以到 wiki 網頁觀看範例。

講了這麼多,以 C++Template 來說,它到底是屬於哪類呢?
答案就是:既屬於 Static Typing 又屬於 Duck Typing。

class Foo { void quack() {} }; class Bar { void quack() {} }; class Baz {}; template void f(Duck d) { d.quack(); } int main() { f(Foo()); // works f(Bar()); // works f(Baz()); // compile error because Baz does not have a quack method return 0; }