蘋果新貴 Swift 之前世今生

池建強發表於2014-06-11

  上週出差勞頓,這篇文章幾次動筆都未完成,常常躺倒床上就昏睡過去。南方的天氣悶熱潮溼,讓我感到極度的不適應,等到回到北方,天高雲清,空氣乾爽,讓人產生一種「解放區的天是明朗的天」的感覺,我甚至覺得自己的手機、Pad 和 Mac 都滿血復活了……直到有人提醒說它們是因為充電和網速的原因。好吧,南方酒店的網路還真叫慢啊……

  以下是正文:

  Swift

  2010年的夏天,Chris Lattner 接到了一個不同尋常的任務:為 OS X 和 iOS 平臺開發下一代新的程式語言。那時候賈伯斯還在以帶病之身掌控著龐大的蘋果帝國,他是否參與了這個研發計劃,我們不得而知,不過我想他至少應該知道此事,因為這個計劃是高度機密的,只有極少數人知道,最初的執行者也只有一個人,那就是 Chris Lattner。

  從2010年的7月起,克里斯(Chris)就開始了無休止的思考、設計、程式設計和除錯,他用了近一年的時間實現了大部分基礎語言結構,之後另一些語言專家加入進來持續改進。到了2013年,該專案成為了蘋果開發工具組的重中之重,克里斯帶領著他的團隊逐步完成了一門全新語言的語法設計、編譯器、執行時、框架、IDE 和文件等相關工作,並在2014年的 WWDC 大會上首次登臺亮相便震驚了世界,這門語言的名字叫做:「Swift」。

  根據克里斯個人部落格(http://nondot.org/sabre/ )對 Swift 的描述,這門語言幾乎是他憑藉一己之力完成的。這位著名的70後程式設計師同時還是 LLVM 專案的主要發起人與作者之一、Clang 編譯器的作者,可以說 Swift 語言和克里斯之前的軟體作品有著千絲萬縷的聯絡。

同樣是70後程式設計師,差別怎麼那麼大呢?

  關於作者

  克里斯可以說是天才少年和好學生的代名詞,他在2000年本科畢業之後,繼續攻讀計算機碩士和博士。但克里斯並不是宅男,學習之餘他手捧「龍書」遊歷世界,成為德智體美勞全面發展的好學生。之後就是一篇又一篇的發表論文,碩士畢業論文即提出了一套完整的執行時編譯思想,奠定了 LLVM 的發展基礎,讀博期間 LLVM 編譯框架在他的領導下得到了長足的發展,已經可以基於 GCC 前端編譯器的語義分析結果進行編譯優化和程式碼生成,所以克里斯在2005年畢業的時候已經是業界知名的編譯器專家了。

注:很多計算機專業的大學生經常問我在大學裡學點什麼好,看看克里斯就行了。以目前的科技資訊開放程度,如果你在自己感興趣的領域裡用心耕耘,再加上那麼一點點天分,畢業時成為某一個專有領域的專家應該不是問題。那時就不是你滿世界去找工作了,而是工作滿世界來找你!

  克里斯畢業的時候正是蘋果為了編譯器焦頭爛額的時候,因為蘋果之前的軟體產品都依賴於整條 GCC 編譯鏈,而開源界的這幫大爺並不買蘋果的帳,他們不願意專門為了蘋果公司的要求優化和改進 GCC 程式碼,所以蘋果一怒之下將編譯器後端直接替換為 LLVM,並且把克里斯招入麾下。克里斯進入了蘋果之後如魚得水,不僅大幅度優化和改進 LLVM 以適應 Objective-C 的語法變革和效能要求,同時發起了 CLang 專案,旨在全面替換 GCC。這個目標目前已經實現了,從 OS X10.9和 XCode 5開始,LLVM+GCC 已經被替換成了 LLVM+Clang。

  Swift 是克里斯在 LLVM 和 Clang 之後第三個偉大的專案!

  關於語言

  2007年之前,Objective-C 一直是蘋果自家院落的小眾語言,但是 iOS 移動裝置的爆發讓這門語言的普及率獲得了火箭一般的躥升速度,截止到今天,Objective-C 在程式語言排行榜上排名第三,江湖人稱三哥,大哥二哥分別是 C 和 Java 這樣的老牌語言。同時,蘋果在2012年和2013年分別對 Objective-C 進行了大規模的優化和升級改進,增加了各種現代語言的特性,讓編寫 App 更加容易,更多的程式設計師投入到了 App Store 的生態圈裡……

  在這種情況下,蘋果公司為什麼會發布一門新語言呢?

  這個問題沒有標準答案,不過我們可以試著去分析一下,談談蘋果的心路歷程……

  Objective-C 是80年代初 Brad Cox 和 Tom Love 發明的,1988年賈伯斯的 Next 公司獲得了這門程式語言語言的授權,並開發出了Objective-C 的語言庫和NEXTSTEP的開發環境。後來 Next 被蘋果收購,Objective-C 陰差陽錯成了蘋果的當家語言。掐指一算,三十年倏忽而過,OC 也成長為爺爺輩兒的程式語言了。

  為了伺候好這位「爺爺」,蘋果煞費苦心,把 GCC 的編譯鏈先替換成 LLVM +GCC,又替換成 LLVM+Clang,做語法簡化、自動引用計數、增加 Blocks 和 GCD 多執行緒非同步處理技術……終於,OC 在30年後重新煥發出勃勃生機,並佔據了兵器譜排名第三的位置。但是,蘋果卻有點煩了,OC 改進了這麼多年,怎麼看都像是在修修補補,用 Blocks 去實現一個類似 Python 的 lambda 閉包功能,看起來總是那麼彆扭。好吧,既然已經全盤掌握了 LLVM 和 Clang,為什麼我們不去基於現在的編譯器設計一門全新的語言呢?一門屬於蘋果的語言!你看,鄰居谷歌家裡叫做 Go 的孩子不是玩耍正酣麼?

  於是 Swift 誕生了……

  當然,事實的真相也可能是行動緩慢的喬老爺子把克里斯拉到一邊說:

  「I want to be swift to……」

  「 行了,您別說了,不就是想要 swift 嗎,我這就給您做一個去」

  於是 Swift 誕生了……

  語法

  Swift 是一門博採眾長的現代語言,在設計的過程中,克里斯參考了Objective-C,Rust,Haskell,Ruby,Python,C#等優秀語言的特點,最終形成了目前 Swift 的語法特性。我在閱讀了官方教程和做了些程式碼實驗之後,自我感覺會喜歡上這門語言,在這裡簡單談點感想,更深入的內容需要你們自己去深入學習。

  1、Swift 是面向 Cocoa 和 Cocoa Touch 的程式語言,編譯型語言,生產環境的程式碼都需要 LLVM 編譯成原生程式碼才能執行,但是Swift又具備很多動態語言的語法特性和互動方式。

  2、Swift 是一門型別安全的語言,可以幫助開發者清楚的掌控程式碼片段中的值型別。如果你期望輸入的是字串,型別安全的特性會阻止開發者錯誤地為其傳遞一個整數。這一切使得開發者能夠更早的發現和修復錯誤。

  3、支援各種高階語言特性,包括閉包、泛型、物件導向、多返回值、型別介面、元組、集合等。

  4、Swift 能與 Objective-C 進行混合程式設計,但程式碼分屬不同的檔案。

  5、全面的Unicode支援,你甚至可以用一隻?作為變數名,實現以下操作:

let ? = "大狗菠蘿"
for n in ?{
println( n )
}

  控制檯會輸出「大狗菠蘿」四個字。

  6、程式設計語句取消了大部分語言使用的「;」分隔符,只有一行寫多條語句時才需要分號。

  7、很多人簡單閱讀了 Swift 的資料型別,就認為 Swift 沒有類似 Set、List 這樣的資料結構,其實Swift 提供了兩種 Collection 的資料型別:陣列(Array)和字典(Dictionary),兩個資料型別的表示式都用中括號標識。其中陣列可以儲存任意型別的變數,也可以強制宣告儲存同一種型別的變數。同時陣列提供了類似 Set 功能,你可以修改、追加、替換和刪除資料的元素。另外,Swift 還提供了元組(Tuple)的功能支援函式多返回值。

  8、Swift 沒有提供顯式的指標,引數傳遞根據資料型別的不同分為值型別和引用型別,值傳遞進行記憶體拷貝,引用傳遞最終傳遞的是一個指向原有物件的指標。這一點和 Java 的引數傳遞是類似的。需要注意的一點是,Swift 裡的陣列和字典雖然都是結構體(struct),但在引數傳遞過程中處理方式卻不一樣,預設 Array 是引用傳遞,Dictionary 是值傳遞。而在 Java 中,由於陣列和 Map 都是物件,所以傳遞的都是指標。

  在 Swift 中,如果你不想傳遞陣列引用,可以用 copy() 方法先複製一份出來,另外,也可以用 unshare() 表示,本變數不傳遞指標。

  9、閉包,Swift 終於提供了一種優雅的閉包解決方案,比如在排序函式 sort 中進行函式傳遞:

let names = ["D", "B", "R", "C", "A"]
func backwards(s1: String, s2: String) -> Bool {
return s1 > s2
}
var rnames = sort(names, backwards)

  事實上更簡單的寫法是:

var rnames = sort( ["D", "B", "R", "C", "A"] ) { $0 > $1 }

  10、可選變數(Optional)的引入主要是為了應對一個變數可能存在也可能是 nil 的情況,這種情況在很多高階語言裡都存在。比如你想使用String的toInt方法將String轉化為 Int 型別,但是你並不知道這個轉化是否正常,這時候系統會返回一個可選變數,如果轉換成功就返回正常值,轉換失敗就返回 nil,如下:

let str = "123A"
let nn = str.toInt()

  這是 nn 就是可選變數,想得到 nn 的值,可以通過 if 進行判斷並通過追加感嘆號獲取變數值,如下:

if nn {
println(nn!)
}

  可選變數的引入解決了大部分需要顯式處理的異常,這部分工作也扔給編譯器去做了。想了解更多可選變數的用法,請閱讀蘋果的官方文件。

  11、Swift 中的 nil 和 Objective-C 中的 nil 不同。在 Objective-C 中,nil 是指向不存在物件的指標,而在 Swift 裡,nil 不是指標,它表示特定型別的值不存在。所有型別的可選值都可以被設定為nil,不僅僅是物件型別。

  12、Swift 沒有從語言層面支援非同步和多核,不過可以直接在 Swift 中複用 GCD 的 API 實現非同步功能。另外沒看到 Swift 的異常處理機制,可能有了可選變數,異常的使用會非常少吧。

  關於語法相關的內容,先寫這麼幾點吧。

  給大家推薦一篇王巍 (@onevcat)寫的「行走於 Swift 的世界中」,深入閱讀必有收穫。

  http://onevcat.com/2014/06/walk-in-swift/

  基本上,Swift 絕對不是玩具語言,而是一門可以被大眾接受的工業級程式語言。相信假以時日,Swift 必將在 App 開發領域大放異彩。

  效能

  Swift 在 WWDC 上展示出來的效能還是讓人非常吃驚的,在進行復雜物件排序時,OC 的效能是 Python 的2.8倍,Swift 是 Python 的3.9倍;在實現 RC4加密演算法的時候,OC 的效能是 Python 的127倍,Swift 是 Python 的220倍。總之 Python 在某一個深坑裡膝蓋中箭了,OC 也沒好到哪去,而 Swift,就是快啊就是快!

  對於這一點我並不是很理解,首先是 WWDC 上展示的語言層面的基準測試過於簡單了,另外,OC 和 Swift 都是被 LLVM 編譯成原生程式碼執行的,理論上針對 Swift 的優化同樣可以應用於 OC,但是 Swift 居然比 OC 快那麼一點點,難道 LLVM 單獨針對 Swift 做了優化麼?我表示不明覺厲。

  當然,還有更較真的程式設計師,他在第一時間針對於迴圈、遞增、陣列、字串拼接等功能進行了測試,發現 Swift 的效能比 OC 還是差那麼一點點的(http://www.splasmata.com/?p=2798 )。

  無論這些測試資料是否準確,我覺得效能是我們最不需要擔心的問題,蘋果已經全盤掌握了這個語言的方方面面,從底層編譯框架到編譯器再到語言設計,優化之路才剛剛開始,我們只要給這門新語言一點耐心就可以了。

  所碼即所得(Playground)

Playground

  對於開發者來說,Playground 是本次 WWDC 最大的亮點。能夠在編碼的同時實時預覽輸出結果是每個開發人員的夢想,這一次蘋果為大家提供了這樣的福利。

  Playground 不僅實現了很多指令碼語言支援的互動式程式設計,而且提供控制檯輸出、實時圖形影像、時間線(timeline)變數跟蹤等功能,開發者除了可以看到程式碼的實時執行結果,還能根據時間線閱讀某個變數在程式碼片段中值的變化。這真是太棒了!

  最初看到這個功能的時候我甚至以為每個 Swift 檔案都可以基於 Playground 進行實時編碼預覽,仔細閱讀文件後發現,只能在 XCode 提供的 Playground 檔案中實現以上功能。看來 Playground 顧名思義,目前還只是為開發者提供了一個玩耍程式碼的地方。

  當然不僅僅是玩耍,我們可以基於 Playground 做這些事情:

  1、學習:通過 Playground 學習 Swift,製作 Swift 教程實現互動式學習,同時還可以培訓其他初學者。

  2、程式碼開發:執行演算法程式,迅速看到演算法結果,跟蹤變數;執行繪圖程式,即時看到影像結果,及時調整。執行通用程式碼,檢視變數的改變情況。

  3、實驗性程式碼:無需建立專案,直接開啟一個獨立的Playground檔案即可編寫程式碼,嘗試呼叫新的 API。

  對於 Playground,設計者克里斯是這樣描述的:Playground 功能傾注了我個人很多心血和激情,我希望新的程式語言具備更好互動性,更友好和有趣……我們希望通過這門語言重新定義「如何教授電腦科學!」

  開始使用 Swift

  作為一門新語言,Swift 定位非常明確,就是吸引更多的開發者加入蘋果的軟體生態圈,為 iOS 和 OS X 開發出更為豐富的 App,如果你是 App Store 的開發者,推薦儘早學習和掌握這門蘋果力推的新語言。對於大部分新事物來說,越早介入,獲利越多。如果你是一名 Web 相關的開發者,與其等待 Swift 增加 Web 開發的相關特性,還不如去學習一下 Go 語言 Web 程式設計。

  如何開始 Swift 呢?

  1、下載 Xcode6-Beta 版本。

  2、下載蘋果官方提供 Swift 程式語言電子書(https://itunes.apple.com/cn/book/swift-programming-language/id881256329?mt=11 ),中文版本:http://yuedu.baidu.com/ebook/6f6c3b1ef01dc281e43af000 。讀。

  3、下載 WWDC Swift 的 Session 視訊和PDF。看。

  4、基於 Xcode6建立 Swfit 語言的專案,在專案中建立Playground,在其中除錯玩耍。

  5、根據官方提供的 GuidedTour.playground 學習 Swift 語法特性。下載地址: https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/GuidedTour.playground.zip

  6、熟悉了基本的語法特性、與 OC 的混用、與 Cocoa 和 Cocoa Touch的互動、除錯等功能之後,就可以構建你的第一個Swift App 了。

  可以說 Swift 是我所見過關注度最高的新語言,一經推出即萬眾矚目,媒體和開發者在數天之內對 Swift 進行了長篇累牘的報導和討論,英文手冊迅速被翻譯成中文,即使是江湖上的另一位大佬谷歌 2009 年推出 Go 語言時也沒有如此浩大的聲勢。當然,這和 Go 語言的定位有關,作為一門系統級的伺服器端語言,開發者的可選餘地太大了,如果谷歌推出 Go 是用來取代 Java 開發 Android App,那可能情況就完全不一樣了。

  經過 WWDC2014,蘋果已經完全體現出了一個軟體公司的創新能力和技術底蘊,無論是作業系統,程式語言,還是應用開發,蘋果都已經準備好了,凝神靜氣,蓄勢待發。作為開發者,我們要做的就是:Write the code, Change the world,然後期待下一個收穫的季節!

相關文章