可檢驗屬性。靜態類型系統可以保證消除某些運行時的錯誤。例如可以保證:布爾型不會與
整數型相加;私有變量不會從類的外部被訪問;用正確數量的參數調用了函數;字符串集只能加入
字符串。
不過當前的靜態類型系統還不能查到其他類型的錯誤。比方說,通常查不到無法終結的函數,數組
越界,或除零錯誤。同樣也查不到你的程序不符合規格說明書(假設有這么一份規格說明書)。因
此有些人認為靜態類型系統不太有用而忽視它。批評說既然這種類型系統只能發現簡單錯誤,而單
元測試能提供更廣泛的覆蓋,那又為何自尋煩惱使用靜態類型呢?我們認為這種說法不正確。盡管
靜態類型系統確實不能替代單元測試,但是卻能減少用來測試這些屬性的單元測試的數量。同樣,
單元測試也不能替代靜態類型。總而言之,如Edsger Dijkstra 所說,測試只能證明存在錯誤,而非
不存在。14因此,靜態類型能給的保證或許很簡單,但這些保證無論多少測試都給不了。
安全的重構。靜態類型系統提供了讓你具有高度信心去變動代碼基礎的安全網。試想一個給
方法新增參數的重構實例。在靜態類型語言中,你可以完成修改,重編譯你的系統并簡單地修改所
有引起類型錯誤的代碼行。一旦完成了這些,你可以確信已經發現了所有需要修改的地方。這種信
心對于其他的簡單重構,如改變方法名或把方法從一個類移到另一個,都會有效。靜態類型檢查會
在所有的例子中提供足夠的確信,表明新系統和舊系統可以一樣的工作。
文檔。靜態類型是被編譯器檢查過正確性的程序文檔。不像普通的注釋,類型標注永遠都不
會過期(至少如果包含它的源文件近期剛剛通過編譯就不會)。更進一步說,編譯器和集成開發環
境可以利用類型標注提供更好的上下文幫助。舉例來說,集成開發環境可以通過判定選中表達式的
靜態類型,找到類型的所有成員,并全部顯示出來。
def f(x: String) = ...
知道f 的變量應該是String 是有用的。另一方面,以下例子中兩個標注至少有一個是討厭的:
val x: HashMap[Int, String] = new HashMap[Int, String]()
很明顯,x 是以Int 為鍵,String 為值的HashMap 這句話說一遍就夠了;同樣的句子沒必要重
復兩遍。
Scala 有非常精于此道的類型推斷系統,能讓你省略幾乎所有的通常被認為是討厭的類型信息。前面
的例子可以改寫成以下兩種方式:
val x = new HashMap[Int, String]()
val x: Map[Int, String] = new HashMap()
Scala 里的類型推斷不止于此。實際上,就算用戶代碼絲毫沒有顯式類型也不稀奇。因此,Scala 程
序經常看上去有點像是動態類型腳本語言寫出來的程序。尤其在客戶應用代碼中作為預編譯代碼庫
控件的膠水代碼時,表現得更為顯著。而對于庫控件來說不是這么回事,因為它們常常用到相當精
妙的類型去使其適于靈活使用的模式。這是由代碼的實際情況決定的。畢竟,構成可重用控件接口
的成員的類型符號應該是顯式給出的,因為它們構成了控件和它的使用者間契約的重要部分。