編者注釋:本文轉(zhuǎn)自微信公眾號(hào) MacTalk By 池建強(qiáng) ,原文《 蘋果新貴 Swift 之前世今生 》
2010 年的夏天,Chris Lattner 接到了一個(gè)不同尋常的任務(wù):為 OS X 和 iOS 平臺(tái)開發(fā)下一代新的編程語(yǔ)言。那時(shí)候喬布斯還在以帶病之身掌控著龐大的蘋果帝國(guó),他是否參與了這個(gè)研發(fā)計(jì)劃,我們不得而知,不過我想他至少應(yīng)該知道此事,因?yàn)檫@個(gè)計(jì)劃是高度機(jī)密的,只有極少數(shù)人知道,最初的執(zhí)行者也只有一個(gè)人,那就是 Chris Lattner。
從 2010 年的 7 月起,克里斯(Chris)就開始了無休止的思考、設(shè)計(jì)、編程和調(diào)試,他用了近一年的時(shí)間實(shí)現(xiàn)了大部分基礎(chǔ)語(yǔ)言結(jié)構(gòu),之后另一些語(yǔ)言專家加入進(jìn)來持續(xù)改進(jìn)。到了 2013 年,該項(xiàng)目成為了蘋果開發(fā)工具組的重中之重,克里斯帶領(lǐng)著他的團(tuán)隊(duì)逐步完成了一門全新語(yǔ)言的語(yǔ)法設(shè)計(jì)、編譯器、運(yùn)行時(shí)、框架、IDE 和文檔等相關(guān)工作,并在 2014 年的 WWDC 大會(huì)上首次登臺(tái)亮相便震驚了世界,這門語(yǔ)言的名字叫做:「Swift」。
根據(jù)克里斯個(gè)人博客( http://nondot.org/sabre/ )對(duì) Swift 的描述,這門語(yǔ)言幾乎是他憑借一己之力完成的。這位著名的 70 后程序員同時(shí)還是 LLVM 項(xiàng)目的主要發(fā)起人與作者之一、Clang 編譯器的作者,可以說 Swift 語(yǔ)言和克里斯之前的軟件作品有著千絲萬縷的聯(lián)系。
同樣是70后程序員,差別怎么那么大呢?
關(guān)于作者
克里斯可以說是天才少年和好學(xué)生的代名詞,他在 2000 年本科畢業(yè)之后,繼續(xù)攻讀計(jì)算機(jī)碩士和博士。但克里斯并不是宅男,學(xué)習(xí)之余他手捧「龍書」游歷世界,成為德智體美勞全面發(fā)展的好學(xué)生。之后就是一篇又一篇的發(fā)表論文,碩士畢業(yè)論文即提出了一套完整的運(yùn)行時(shí)編譯思想,奠定了 LLVM 的發(fā)展基礎(chǔ),讀博期間 LLVM 編譯框架在他的領(lǐng)導(dǎo)下得到了長(zhǎng)足的發(fā)展,已經(jīng)可以基于 GCC 前端編譯器的語(yǔ)義分析結(jié)果進(jìn)行編譯優(yōu)化和代碼生成,所以克里斯在 2005 年畢業(yè)的時(shí)候已經(jīng)是業(yè)界知名的編譯器專家了。
注:很多計(jì)算機(jī)專業(yè)的大學(xué)生經(jīng)常問我在大學(xué)里學(xué)點(diǎn)什么好,看看克里斯就行了。以目前的科技信息開放程度,如果你在自己感興趣的領(lǐng)域里用心耕耘,再加上那么一點(diǎn)點(diǎn)天分,畢業(yè)時(shí)成為某一個(gè)專有領(lǐng)域的專家應(yīng)該不是問題。那時(shí)就不是你滿世界去找工作了,而是工作滿世界來找你! ?
克里斯畢業(yè)的時(shí)候正是蘋果為了編譯器焦頭爛額的時(shí)候,因?yàn)樘O果之前的軟件產(chǎn)品都依賴于整條 GCC 編譯鏈,而開源界的這幫大爺并不買蘋果的帳,他們不愿意專門為了蘋果公司的要求優(yōu)化和改進(jìn) GCC 代碼,所以蘋果一怒之下將編譯器后端直接替換為 LLVM,并且把克里斯招入麾下。克里斯進(jìn)入了蘋果之后如魚得水,不僅大幅度優(yōu)化和改進(jìn) LLVM 以適應(yīng) Objective-C 的語(yǔ)法變革和性能要求,同時(shí)發(fā)起了 CLang 項(xiàng)目,旨在全面替換 GCC。這個(gè)目標(biāo)目前已經(jīng)實(shí)現(xiàn)了,從 OS X10.9 和 XCode 5 開始,LLVM+GCC 已經(jīng)被替換成了 LLVM+Clang。
Swift 是克里斯在 LLVM 和 Clang 之后第三個(gè)偉大的項(xiàng)目!
關(guān)于語(yǔ)言
2007 年之前,Objective-C 一直是蘋果自家院落的小眾語(yǔ)言,但是 iOS 移動(dòng)設(shè)備的爆發(fā)讓這門語(yǔ)言的普及率獲得了火箭一般的躥升速度,截止到今天,Objective-C 在編程語(yǔ)言排行榜上排名第三,江湖人稱三哥,大哥二哥分別是 C 和 Java 這樣的老牌語(yǔ)言。同時(shí),蘋果在 2012 年和 2013 年分別對(duì) Objective-C 進(jìn)行了大規(guī)模的優(yōu)化和升級(jí)改進(jìn),增加了各種現(xiàn)代語(yǔ)言的特性,讓編寫 App 更加容易,更多的程序員投入到了 App Store 的生態(tài)圈里……
在這種情況下,蘋果公司為什么會(huì)發(fā)布一門新語(yǔ)言呢?
這個(gè)問題沒有標(biāo)準(zhǔn)答案,不過我們可以試著去分析一下,談?wù)勌O果的心路歷程……
Objective-C 是 80 年代初 Brad Cox 和 Tom Love 發(fā)明的,1988 年喬布斯的 Next 公司獲得了這門編程語(yǔ)言語(yǔ)言的授權(quán),并開發(fā)出了Objective-C 的語(yǔ)言庫(kù)和 NEXTSTEP 的開發(fā)環(huán)境。后來 Next 被蘋果收購(gòu),Objective-C 陰差陽(yáng)錯(cuò)成了蘋果的當(dāng)家語(yǔ)言。掐指一算,三十年倏忽而過,OC 也成長(zhǎng)為爺爺輩兒的編程語(yǔ)言了。
為了伺候好這位「爺爺」,蘋果煞費(fèi)苦心,把 GCC 的編譯鏈先替換成 LLVM +GCC,又替換成 LLVM+Clang,做語(yǔ)法簡(jiǎn)化、自動(dòng)引用計(jì)數(shù)、增加 Blocks 和 GCD 多線程異步處理技術(shù)……終于,OC 在 30 年后重新煥發(fā)出勃勃生機(jī),并占據(jù)了兵器譜排名第三的位置。但是,蘋果卻有點(diǎn)煩了,OC 改進(jìn)了這么多年,怎么看都像是在修修補(bǔ)補(bǔ),用 Blocks 去實(shí)現(xiàn)一個(gè)類似 Python 的 lambda 閉包功能,看起來總是那么別扭。好吧,既然已經(jīng)全盤掌握了 LLVM 和 Clang,為什么我們不去基于現(xiàn)在的編譯器設(shè)計(jì)一門全新的語(yǔ)言呢?一門屬于蘋果的語(yǔ)言!你看,鄰居谷歌家里叫做 Go 的孩子不是玩耍正酣么?
于是 Swift 誕生了……
當(dāng)然,事實(shí)的真相也可能是行動(dòng)緩慢的喬老爺子把克里斯拉到一邊說:
「I want to be swift to……」
「 行了,您別說了,不就是想要 swift 嗎,我這就給您做一個(gè)去」
于是 Swift 誕生了……
語(yǔ)法
Swift 是一門博采眾長(zhǎng)的現(xiàn)代語(yǔ)言,在設(shè)計(jì)的過程中,克里斯參考了 Objective-C,Rust,Haskell,Ruby,Python,C# 等優(yōu)秀語(yǔ)言的特點(diǎn),最終形成了目前 Swift 的語(yǔ)法特性。我在閱讀了官方教程和做了些代碼實(shí)驗(yàn)之后,自我感覺會(huì)喜歡上這門語(yǔ)言,在這里簡(jiǎn)單談點(diǎn)感想,更深入的內(nèi)容需要你們自己去深入學(xué)習(xí)。
1、Swift 是面向 Cocoa 和 Cocoa Touch 的編程語(yǔ)言,編譯型語(yǔ)言,生產(chǎn)環(huán)境的代碼都需要 LLVM 編譯成本地代碼才能執(zhí)行,但是Swift又具備很多動(dòng)態(tài)語(yǔ)言的語(yǔ)法特性和交互方式。
2、Swift 是一門類型安全的語(yǔ)言,可以幫助開發(fā)者清楚的掌控代碼片段中的值類型。如果你期望輸入的是字符串,類型安全的特性會(huì)阻止開發(fā)者錯(cuò)誤地為其傳遞一個(gè)整數(shù)。這一切使得開發(fā)者能夠更早的發(fā)現(xiàn)和修復(fù)錯(cuò)誤。
3、支持各種高級(jí)語(yǔ)言特性,包括閉包、泛型、面向?qū)ο蟆⒍喾祷刂怠㈩愋徒涌凇⒃M、集合等。
4、Swift 能與 Objective-C 進(jìn)行混合編程,但代碼分屬不同的文件。
5、全面的Unicode支持,你甚至可以用一顆 ? 作為變量名,實(shí)現(xiàn)以下操作:
let ? = "大狗菠蘿"
for n in ?{
? ? println( n )
}
控制臺(tái)會(huì)輸出「大狗菠蘿」四個(gè)字。
6、編程語(yǔ)句取消了大部分語(yǔ)言使用的「;」分隔符,只有一行寫多條語(yǔ)句時(shí)才需要分號(hào)。
7、很多人簡(jiǎn)單閱讀了 Swift 的數(shù)據(jù)類型,就認(rèn)為 Swift 沒有類似 Set、List 這樣的數(shù)據(jù)結(jié)構(gòu),其實(shí)Swift 提供了兩種 Collection 的數(shù)據(jù)類型:數(shù)組(Array)和字典(Dictionary),兩個(gè)數(shù)據(jù)類型的表達(dá)式都用中括號(hào)標(biāo)識(shí)。其中數(shù)組可以存儲(chǔ)任意類型的變量,也可以強(qiáng)制聲明存儲(chǔ)同一種類型的變量。同時(shí)數(shù)組提供了類似 Set 功能,你可以修改、追加、替換和刪除數(shù)據(jù)的元素。另外,Swift 還提供了元組(Tuple)的功能支持函數(shù)多返回值。
8、Swift 沒有提供顯式的指針,參數(shù)傳遞根據(jù)數(shù)據(jù)類型的不同分為值類型和引用類型,值傳遞進(jìn)行內(nèi)存拷貝,引用傳遞最終傳遞的是一個(gè)指向原有對(duì)象的指針。這一點(diǎn)和 Java 的參數(shù)傳遞是類似的。需要注意的一點(diǎn)是,Swift 里的數(shù)組和字典雖然都是結(jié)構(gòu)體(struct),但在參數(shù)傳遞過程中處理方式卻不一樣,默認(rèn) Array 是引用傳遞,Dictionary 是值傳遞。而在 Java 中,由于數(shù)組和 Map 都是對(duì)象,所以傳遞的都是指針。
在 Swift 中,如果你不想傳遞數(shù)組引用,可以用 copy() 方法先復(fù)制一份出來,另外,也可以用 unshare() 表示,本變量不傳遞指針。
9、閉包,Swift 終于提供了一種優(yōu)雅的閉包解決方案,比如在排序函數(shù) sort 中進(jìn)行函數(shù)傳遞:
let names = ["D", "B", "R", "C", "A"]
func backwards(s1: String, s2: String) -> Bool {
? ? return s1 > s2
}
var rnames = sort(names, backwards)
事實(shí)上更簡(jiǎn)單的寫法是:
var rnames = sort( ["D", "B", "R", "C", "A"] ) { $0 > $1 }
10、可選變量(Optional)的引入主要是為了應(yīng)對(duì)一個(gè)變量可能存在也可能是 nil 的情況,這種情況在很多高級(jí)語(yǔ)言里都存在。比如你想使用String的toInt方法將String轉(zhuǎn)化為 Int 類型,但是你并不知道這個(gè)轉(zhuǎn)化是否正常,這時(shí)候系統(tǒng)會(huì)返回一個(gè)可選變量,如果轉(zhuǎn)換成功就返回正常值,轉(zhuǎn)換失敗就返回 nil,如下:
let str = "123A"
let nn = str.toInt()
這是 nn 就是可選變量,想得到 nn 的值,可以通過 if 進(jìn)行判斷并通過追加感嘆號(hào)獲取變量值,如下:
if nn {
? ? println(nn!)
}
可選變量的引入解決了大部分需要顯式處理的異常,這部分工作也扔給編譯器去做了。想了解更多可選變量的用法,請(qǐng)閱讀蘋果的官方文檔。
11、Swift 中的 nil 和 Objective-C 種的 nil 不同。在 Objective-C 中,nil 是指向不存在對(duì)象的指針,而在 Swift 里,nil 不是指針,它表示特定類型的值不存在。所有類型的可選值都可以被設(shè)置為nil,不僅僅是對(duì)象類型。
12、Swift 沒有從語(yǔ)言層面支持異步和多核,不過可以直接在 Swift 中復(fù)用 GCD 的 API 實(shí)現(xiàn)異步功能。另外沒看到 Swift 的異常處理機(jī)制,可能有了可選變量,異常的使用會(huì)非常少吧。
關(guān)于語(yǔ)法相關(guān)的內(nèi)容,先寫這么幾點(diǎn)吧。
給大家推薦一篇王巍 (@onevcat)寫的《 行走于 Swift 的世界中 》,深入閱讀必有收獲。
基本上,Swift 絕對(duì)不是玩具語(yǔ)言,而是一門可以被大眾接受的工業(yè)級(jí)編程語(yǔ)言。相信假以時(shí)日,Swift 必將在 App 開發(fā)領(lǐng)域大放異彩。
性能
Swift 在 WWDC 上展示出來的性能還是讓人非常吃驚的,在進(jìn)行復(fù)雜對(duì)象排序時(shí),OC 的性能是 Python 的2.8倍,Swift 是 Python 的3.9倍;在實(shí)現(xiàn) RC4加密算法的時(shí)候,OC 的性能是 Python 的127倍,Swift 是 Python 的220倍。總之 Python 在某一個(gè)深坑里膝蓋中箭了,OC 也沒好到哪去,而 Swift,就是快啊就是快!
對(duì)于這一點(diǎn)我并不是很理解,首先是 WWDC 上展示的語(yǔ)言層面的基準(zhǔn)測(cè)試過于簡(jiǎn)單了,另外,OC 和 Swift 都是被 LLVM 編譯成本地代碼執(zhí)行的,理論上針對(duì) Swift 的優(yōu)化同樣可以應(yīng)用于 OC,但是 Swift 居然比 OC 快那么一點(diǎn)點(diǎn),難道 LLVM 單獨(dú)針對(duì) Swift 做了優(yōu)化么?我表示不明覺厲。
當(dāng)然,還有更較真的程序員,他在第一時(shí)間針對(duì)于循環(huán)、遞增、數(shù)組、字符串拼接等功能進(jìn)行了測(cè)試,發(fā)現(xiàn) Swift 的性能比 OC 還是差那么一點(diǎn)點(diǎn)的(http://www.splasmata.com/?p=2798 )。
無論這些測(cè)試數(shù)據(jù)是否準(zhǔn)確,我覺得性能是我們最不需要擔(dān)心的問題,蘋果已經(jīng)全盤掌握了這個(gè)語(yǔ)言的方方面面,從底層編譯框架到編譯器再到語(yǔ)言設(shè)計(jì),優(yōu)化之路才剛剛開始,我們只要給這門新語(yǔ)言一點(diǎn)耐心就可以了。
所碼即所得(Playground)
對(duì)于開發(fā)者來說,Playground 是本次 WWDC 最大的亮點(diǎn)。能夠在編碼的同時(shí)實(shí)時(shí)預(yù)覽輸出結(jié)果是每個(gè)開發(fā)人員的夢(mèng)想,這一次蘋果為大家提供了這樣的福利。
Playground 不僅實(shí)現(xiàn)了很多腳本語(yǔ)言支持的交互式編程,而且提供控制臺(tái)輸出、實(shí)時(shí)圖形圖像、時(shí)間線(timeline)變量跟蹤等功能,開發(fā)者除了可以看到代碼的實(shí)時(shí)運(yùn)行結(jié)果,還能根據(jù)時(shí)間線閱讀某個(gè)變量在代碼片段中值的變化。這真是太棒了!
最初看到這個(gè)功能的時(shí)候我甚至以為每個(gè) Swift 文件都可以基于 Playground 進(jìn)行實(shí)時(shí)編碼預(yù)覽,仔細(xì)閱讀文檔后發(fā)現(xiàn),只能在 XCode 提供的 Playground 文件中實(shí)現(xiàn)以上功能。看來 Playground 顧名思義,目前還只是為開發(fā)者提供了一個(gè)玩耍代碼的地方。
當(dāng)然不僅僅是玩耍,我們可以基于 Playground 做這些事情:
1、學(xué)習(xí):通過 Playground 學(xué)習(xí) Swift,制作 Swift 教程實(shí)現(xiàn)交互式學(xué)習(xí),同時(shí)還可以培訓(xùn)其他初學(xué)者。
2、代碼開發(fā):執(zhí)行算法程序,迅速看到算法結(jié)果,跟蹤變量;執(zhí)行繪圖程序,即時(shí)看到圖像結(jié)果,及時(shí)調(diào)整。執(zhí)行通用代碼,查看變量的改變情況。
3、實(shí)驗(yàn)性代碼:無需創(chuàng)建項(xiàng)目,直接打開一個(gè)獨(dú)立的Playground文件即可編寫代碼,嘗試調(diào)用新的 API。
對(duì)于 Playground,設(shè)計(jì)者克里斯是這樣描述的:Playground 功能傾注了我個(gè)人很多心血和激情,我希望新的編程語(yǔ)言具備更好交互性,更友好和有趣……我們希望通過這門語(yǔ)言重新定義「如何教授計(jì)算機(jī)科學(xué)!」
開始使用 Swift
作為一門新語(yǔ)言,Swift 定位非常明確,就是吸引更多的開發(fā)者加入蘋果的軟件生態(tài)圈,為 iOS 和 OS X 開發(fā)出更為豐富的 App,如果你是 App Store 的開發(fā)者,推薦盡早學(xué)習(xí)和掌握這門蘋果力推的新語(yǔ)言。對(duì)于大部分新事物來說,越早介入,獲利越多。如果你是一名 Web 相關(guān)的開發(fā)者,與其等待 Swift 增加 Web 開發(fā)的相關(guān)特性,還不如去學(xué)習(xí)一下 Go 語(yǔ)言 Web 編程。
如何開始 Swift 呢?
1、下載 Xcode6-Beta 版本。
2、下載 蘋果官方提供 Swift 編程語(yǔ)言電子書, 中文版本 。
3、下載 WWDC Swift 的 Session 視頻和PDF。看。
4、基于 Xcode6創(chuàng)建 Swfit 語(yǔ)言的項(xiàng)目,在項(xiàng)目中創(chuàng)建Playground,在其中調(diào)試玩耍。
5、根據(jù)官方提供的 GuidedTour.playground 學(xué)習(xí) Swift 語(yǔ)法特性。 下載地址 。
6、熟悉了基本的語(yǔ)法特性、與 OC 的混用、與 Cocoa 和 Cocoa Touch的交互、調(diào)試等功能之后,就可以構(gòu)建你的第一個(gè)Swift App 了。?
可以說 Swift 是我所見過關(guān)注度最高的新語(yǔ)言,一經(jīng)推出即萬眾矚目,媒體和開發(fā)者在數(shù)天之內(nèi)對(duì) Swift 進(jìn)行了長(zhǎng)篇累牘的報(bào)道和討論,英文手冊(cè)迅速被翻譯成中文,即使是江湖上的另一位大佬谷歌 2009 年推出 Go 語(yǔ)言時(shí)也沒有如此浩大的聲勢(shì)。當(dāng)然,這和 Go 語(yǔ)言的定位有關(guān),作為一門系統(tǒng)級(jí)的服務(wù)器端語(yǔ)言,開發(fā)者的可選余地太大了,如果谷歌推出 Go 是用來取代 Java 開發(fā) Android App,那可能情況就完全不一樣了。
經(jīng)過 WWDC2014,蘋果已經(jīng)完全體現(xiàn)出了一個(gè)軟件公司的創(chuàng)新能力和技術(shù)底蘊(yùn),無論是操作系統(tǒng),編程語(yǔ)言,還是應(yīng)用開發(fā),蘋果都已經(jīng)準(zhǔn)備好了,凝神靜氣,蓄勢(shì)待發(fā)。作為開發(fā)者,我們要做的就是:Write the code, Change the world,然后期待下一個(gè)收獲的季節(jié)!