特設多型ad hoc polymorphism)是程式語言的一種多型,多型函數有多個不同的實現,依賴於其實參而呼叫相應版本的函數。因此,特設多型僅支援有限數量的不同類型。函數多載乃至運算子多載也是特設多型的一種。

概述

編輯

特設多型與參數多型相對。ad hoc在這裏並不是貶義,而是指這類多型並不是型別系統的基本特性,不是像參數多型那樣適用於無窮多的類型,而是針對特定問題的解決方案。

換言之,參數多型對各模板參數的實現,是根據模板的通用(generically)的行為的抽象,即泛型的語意;而特設多型可以針對不同的版本實現完全不同的行為,或曰對於每個不同的模版參數都有單獨的版本來應對。打個比方:假如我們要把原材料切成兩半——

  • 參數多型:只要能「切」,就用工具來切割它;
  • 特設多型:根據原材料是鐵還是木頭還是什麼來選擇不同的工具來切。

歷史

編輯

特設多型的名字來源於其發明人克里斯托弗·斯特雷奇於1967年8月在哥本哈根的電腦程式設計暑期學校發表的著名論文《程式語言中的基礎概念英語Fundamental Concepts in Programming Languages》,該文首次提出了參數多型、特設多型、左值右值等概念。[1]

早繫結

編輯

多型的早繫結(early binding)是在編譯期,編譯器完成多型的分派機制:把多型函數、多型類型的名字根據模板參數繫結到具體的模板實現。

晚繫結

編輯

多型的晚繫結英語Late binding是在執行期,程式確定即將要呼叫的多型函數的實現。Smalltalk實現了這種晚繫結機制。

例子

編輯

加法運算子+假設可以運用到如下的情形:

  1. 1 + 2 = 3
  2. 3.14 + 0.0015 = 3.1415
  3. 1 + 3.7 = 4.7
  4. [1, 2, 3] + [4, 5, 6] = [1, 2, 3, 4, 5, 6]
  5. [true, false] + [false, true] = [true, false, false, true]
  6. "bab" + "oon" = "baboon"

多載

編輯

為此,需要的多載實現:

  • 第一種情形,需要整型加法;
  • 第二、第三種情形,需要浮點型加法。其中第三種情形需要隱式類型轉換(type coercion)。
  • 第四、第五種情形,需要list連接操作;
  • 第六種情形,需要字串字面量英語literal string的連接操作。

因此,運算子名字+實際上使用了三到四種完全不同的函數實現。

參考文獻

編輯
  1. ^ C. Strachey, Fundamental concepts in programming languages. Lecture notes for International Summer School in Computer Programming, Copenhagen, August 1967