Swift 的類型體系

猛戳看最終版@SwiftGG

Brent Simmons 在 解決目前不存在的問題,就好像問題存在一樣 中說到:

Swift 的類型體系解決了我沒碰到的一個問題。

對這句話我深有同感,而且我敢打賭很多其他的 Objective-C 開發者也會這樣覺得。

在我剛開始嘗試使用 Swift 時,編譯器似乎經常和我做對 1 。但隨着我對這門語言越來越熟悉,情況也隨之變得好起來,但是有時它奇怪的錯誤信息還是會讓我覺得它是一個難以取悅的任性小孩。

在這樣的情況下,Swift 嚴格的類型檢查所帶給你的好處相比你爲了讓代碼運行所付出的努力就少之又少了。即便如此,它的類型體系還是在去年成長到了讓我再也不想錯過它的程度。

Swift 更好理解

相比 Objective-C 我更喜歡 Swift 最大的原因不是他的類型體系,而是一些更平凡的特性

  • 一等公民值類型。可以把 integer 或者 struct 在不使用 object 包裝的情況下就放到 array 中,這可以說是大贏,因爲這意味着我們可以對這些類型進行擴展。
  • 枚舉有關聯值。還有元組。在 Swift 中構建數據結構模型變得更加清晰。
  • 模式匹配
  • 更清晰的語法且沒有頭文件。

簡而言之,Swift 是現代語言,而 Objective-C 顯然不是。

如果 Apple 在去年發佈了真正的 “Objective-C 3.0”,在保留 Obj-C 動態特性的情況下使其現代化 2 ,我將會更加開心並且可能永遠不會主張更加靜態的類型檢查。畢竟,“我知道我所做的事情,而且我永遠不會因爲數組裏麪包含意外類型而導致錯誤。”

Hole-Driven 開發

但是 Apple 給了我們 Swift, 而不是 Objective-C 3.0。Swift 的發佈促使我去了解其他有同樣類型體系的語言,比如 Haskell,ML 和 Scala。我從那些社區學到的特別的一點就是 hole-driven (或編譯驅動)開發 :不要把編譯器當作需要你對抗的一股力量,而是把它當作可以解決你問題的一件神器,根據類型一步一步滴來。

Hole-Driven 開發在構建數據結構模型和數據轉換時可以說是夢幻般的技術( Haskell 和它的同類尤其擅長),而且儘管還有可提升的潛力,它在 Swift 中依然表現滴相當棒。煩人的編譯器和有益的編譯器最關鍵的不同點在於它的錯誤信息是不是易於理解,而很多 Swift 的診斷信息仍然相當神祕 3

對於典型的 GUI 編程, 編譯驅動開發可能沒那麼有用,儘管我認爲這主要歸根於 Cocoa API 的設計而不是編譯驅動開發固有的限制。像 ReactiveCocoa 這樣的庫就向我們展示了類型體系(在一定程度上說應該是清晰的語法)設計出來的 API 是什麼樣的。當你可以依賴一個幸虧有泛型的編譯器來做多步的 複雜信號變換 ,保證結果的正確性將會變得更加簡單。現在我發現在 Objective-C 中寫這樣的代碼要難得多(隨後也更難理解),因爲我需要在我腦海中記更多的東西。

自動文檔

嚴格的類型體系帶來的另外一個巨大好處就是做爲副產品生成的自動文檔。做爲 Apple 平臺上的開發者,我們訪問不到我們最常使用的庫的源代碼,所以我們需要依賴文檔。編譯器強制 API 設計者提供的信息越多,使用 API 的人就越方便。單可選註釋就給 Cocoa 的文檔提供了極大的提升 4 。想象一下如果所有 Cocoa 的 API 的方法參數和返回值類型都是 id。頭文件基本上就沒什麼用了。

總結

在強制我自己對類型進行非常仔細的思考之後,我發現我 Swift 代碼的設計更好了,也更容易維護了。我對我代碼的正確性也更加有自信了,而且更奇怪的是:寫起來也更有趣了!(PS:此處有強烈的補腎丸廣告即視感)

Swift 仍然在起步階段。有時它可能會讓你沮喪,但是隨着時間的推移編譯器提示的錯誤信息會更友好,甚至可以讓你的代碼更加合理。比如說我們都在糾結的一個例子,併發:如果編譯器可以靜態滴證明你的多線程代碼不存在衝突,那就是一個巨大的優勢。Swift 現在還不能做,但是 Rust 可以 。對次我相當興奮。

1.這也是我覺得 Swift 果斷不是一門易學(易教)語言的原因之一。另外一個就是複雜的標準庫

2.我們幾十年來都在使用“沒有 C 的 Objective-C”,而是以 Smalltalk 的形式

3.毫無疑問,至少有一部分原因是我對語言比較陌生

4.我需要提醒大家的是註釋是不保證正確性的,所以嚴格滴說它們沒有頭文件註釋可靠。也許有人會認爲僅僅一個嚴格的編譯器就可以強制讓 Apple 的文檔更加精確。

發佈了61 篇原創文章 · 獲贊 167 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章