任旻,北京工業大學碩士, 2005年加入微軟中國有限公司,2009年加入騰訊,現任高級工程師,曾負責開發「QQ概念版」、「Q+」、」QQ互聯」、「iPad QQ」等產品。騰訊學院講師,專利達人。一直從事互聯網領域軟件開發和生態系統建設等工做。git
Swift 是一種新的編程語言,用於編寫 iOS 和 OS X 應用。Swift 結合了 C 和 Objective-C 的優勢而且不受C兼容性的限制。Swift 採用安全的編程模式並添加了不少新特性,這將使編程更簡單,更靈活,也更有趣。程序員
首先咱們考察一下Swift到底是一個什麼樣的變成語言。在2014年蘋果的WWDC(世界開發者大會)上,Swift首次亮相。蘋果號稱Swift有3大特性:編程
安全(SAFE)
現代(MODERN)
強大(POWER)數組
例如在下面的代碼中,Swift用關鍵字let聲明常量,關鍵字var聲明變量。安全
在聲明時能夠指定常量和變量的類型,也能夠不指定類型,而是直接賦值。Swift會經過所賦值的類型自動將定義變量的類型。markdown
若是聲明時不進行賦值,那麼每一個類型的變量都有本身的默認值。閉包
例如Double類型的變量,默認值是0。這點與Objective-C、C++和C語言不一樣,不對變量賦值的話,那麼變量的默認值是一個隨機數。若是不注意這點,則很容易由此致使Bug的產生。使用Swift語言則能夠避免這種狀況發生,因此說Swift是類型安全的。app
另外一個安全特性是在流程控制方面。例以下面代碼中switch語句有2個case語句。分別表明legCount爲0和爲1至13奇數的狀況。然而顯然除了這兩種狀況以外,legCount還多是其餘的值,好比:2或15等等。框架
Swift的語法規定,若是case語句不能覆蓋全部可能的狀況,則必須加default語句來處理其餘狀況。不然編譯不能經過。編程語言
這樣能夠避免因爲程序員疏忽,流程沒有被switch-case通過處理,而引發的邏輯錯誤。
咱們能夠看到Swift中的安全特性確實有助於新手減小Bug和邏輯錯誤。可是相似於「變量聲明時就有初始值」的特性在JavaScript,C#等多種現代語言中早已實現了。
在功能強大方面,有一個特性中是對字符串操做的簡化,在下面的代碼中,Swfit能夠用(a)的形式,代替C語言中對字符串format操做。大大簡化了代碼,增長了程序的可讀性。
無獨有偶,在WWDC2015中,蘋果在新版的Safari和WebKit中增長了一個針對JavaScript的新特性。這個特性可使用${變量}的符號,代替傳統的使用「+」對字符串進行拼接的操做。
在項目實踐中,相似的字符串拼接應用較多的是日誌操做。通常都已經封裝成爲組件了。因此,雖然這種語法能夠簡化代碼,但對於工程的影響不大。
例以下面的代碼中能夠直接使用蘋果的emoji圖標寫程序。每個小老鼠的圖標能夠做爲一個字符(character)處理。
網上還有網友利用Swift的這個特性寫了一個諾亞方舟的故事。
另外一個強大的功能是For-in語句的加強。
好比在For-in語句中使用0…4表示循環時取[0,4]的閉區間內整數值。
還能夠在For-in中使用「元組」遍歷Dictionary。
另外用「n…m」的形式表示[n,m]閉區間的語法也能夠應用在switch-case語句中:
以上就是蘋果WWDC2014中對Swift功能強大方面的一些介紹。然而,從上面的例子能夠看出,這些新特性更像是一些語法糖。語法糖在維基百科上的定義以下:
語法糖(Syntactic sugar),也譯爲糖衣語法,指計算機語言中添加的某種語法,這種語法對語言的功能並無影響,可是更方便程序員使用。一般來講使用語法糖可以增長程序的可讀性,從而減小程序代碼出錯的機會。
維基百科上除了有語法糖,還有「語法鹽」和「語法糖精」2個概念。分別表明特別難用的語法,和看似很好用但實際有害的語法。 好比在Swift beta版中,在for-in語句中可使用「n..m」語法,表示從n開始,循環m次。例如:
可是在正式版中,這種寫法被取消了。由於「n..m」和「n…m」這兩種寫法太類似了,若是都保留就會引發混淆,下降程序的可讀性,成爲「語法鹽」或者「語法糖精」了。
如今評價Swift中的新語法是語法糖仍是語法鹽還爲時尚早,須要時間和市場的檢驗。
首先是閉包。在下面的代碼中,repeat函數能夠接受一個閉包類型的task參數。在調用repeat函數時,傳入的第二個參數是一個函數體,其中包含了一行打印語句。
那麼什麼是閉包呢?
閉包有如下3個特色:
提到閉包,想必不少人都會想到JavaScript。咱們就來對比一下JavaScript的閉包。
咱們能夠看到在上述代碼中,sayAlert是閉包,也知足上述3個特色。
其實知足上述3個特色的語法還有不少,只是名字不同而已。好比Java和C#中的Lamda表達式:
這是一段C#代碼,delegate關鍵字用於定義一個函數簽名。好比用del爲名稱,定義了一個參數int返回int的函數。接下來用Lamada表達式定義了函數體爲「x =>x * x」表示返回參數x的平方。
此時myDelegate能夠被調用和傳遞,所以就成爲了一個閉包。
更廣義的說,C中的「指向函數的指針」也知足上述的3個條件。
所以,閉包雖然是現代語言的特性,可是不少語言都支持,並不能算一個很新穎的特性。
在Swift中使用泛型很方便,語法和Java、C#、C++也很相似。
不過使用Objective-C的朋友也有福了,在即將發佈的XCode7中,Objective-C也支持泛型了。
所以咱們大可沒必要由於泛型而轉向Swift。
Swift中還有一個特性是「nullable」的變量類型,也叫可選(Optional)變量。
這是一個很方便的特性。好比一個返回值爲int的函數,能夠經過返回nil來表示函數出錯的狀況。而不須要使用NSError,也不須要經過返回某些特殊int值來表示錯誤,好比「-1」或「-IntMax」。
不過相似的語法在10年前的C# 2.0中就出現了。
以上是微軟官網MSDN上的示例代碼。能夠看到,雙問號「??」操做符也是在C#中先出現的。
以上是蘋果WWCD2014中介紹的Swfit 1.0的特性,在今年的WWDC2015中,蘋果發佈了Swift 2.0。其中增長了一個呼聲特別高的特性:經過相似try-catch的語法支持Error處理。
經過示例代碼能夠看出,Swift支持使用多個catch語句捕獲不一樣類型的Error,並且也支持使用finally語句。
不過這WWDC 2015大會上PPT中的代碼與微軟官方文檔中的一段代碼很是類似:
介紹了這麼多Swift的特性,那麼應該如何評價Swift語言呢?
從客觀上講,Swift中確實包含了「安全、現代、強大」的特性,可是這些特性在其餘語言上早就有支持。所以這些特性與其餘語言相比(包括Objective-C)並無絕對優點。
對於一個編程語言,除了語言特性以外,還能夠從如下3個方面進行比較:
其中代碼效率又能夠分爲代碼的「書寫效率」、「編譯效率」和「運行效率」。若是與 Objective-C比較,Swift在書寫效率上完勝。
在編譯效率上,因爲Swift沒有.h頭文件和一些其餘特性,所以比Objective-C在理論上要快。
可是從實際工程上來說,咱們內部的一個iOS項目,包含了幾千個Objective-C的文件,徹底編譯一次須要30分鐘左右。
對於這種狀況來講,顯然不能經過遷移到Swift來解決,而是須要重構。若是是小型項目,則編譯時間相差就不大了。
對於Swift和Objective-C的運行效率,primateLab進行了一個對比測試。結果以下:
經過右側的平均值對比能夠看出:
所以能夠看出,從運行效率上看,Swift不能徹底勝任全部的場景。
綜上所述:Swift在代碼效率的3各方面,雖然有必定優點,可是還不能由此得出「咱們應該轉向Swift」的結論。
咱們繼續從第三個方面:學習成本上考察Swift。
Swift雖然屬於類C(C-Family)的語言,在保留了大括號,if-else,do-while,swich-case-default 等語法元素以外,也創新了許多新語法。有些語法形式(好比枚舉類型)變化較大。學習Swift語法可能比Objective-C容易一些,可是也不會是零門檻的。
此外使用Swift開發應用必須依賴Cocoa框架,對於以前沒有接觸Cocoa的程序員,這是一塊很大的隱性成本。
這裏引用JavaEye社區創始人Robin的一句話供你們參考:
對程序員來講,熟悉Swift語法也不過一天時間足夠了。關鍵是要提供高級數據類型,簡化Cocoa類庫,不然用不用Swift都沒區別。
Swift語言的學習成本並不像媒體上宣傳得那麼低。因此咱們還須要從第四個方面——生態環境方面進行考察。
生態環境是一個比較抽象的概念。這裏咱們把生態環境簡化爲2個問題:
對於第一個問題,咱們能夠參考一下Github上開源項目的統計數據( http://githut.info ):
Swift雖然在「活躍代碼庫」數量上比較少,可是在「代碼庫平均分支」數量和「代碼庫平均關注者」這兩個指標上都處於領先地位。由此能夠看出,Swift有一羣熱情很是高的愛好者,儘管愛好者絕對數量可能很少,可是加速的趨勢很大。後續的發展是很是值得期待的。
第二個問題「有了問題是否能快速找到結?」,咱們能夠參考一下 Stackflow 網站作的一個調查。其中最流行語言榜單中,與Github同樣,JavaScript排名第一。而Swfit卻沒有入圍。
可是在最受歡迎的語言榜單上,Swift排名第一。
再次證實程序員對Swift的熱情很高。
綜合上面的兩個問題,能夠看出Swift的熱度很高,可是當前成熟度還不夠高。咱們接下來考察生態環境中另外一個因素:框架。
咱們與最流行的JavaScript對比一下。在Google上搜索「JavaScript framework」,能夠看到排名靠前的搜索結果是關於JavaScript框架的對比、排名,以及如何選擇框架的文章,對於一個具體框架的介紹排名在第五位。並且爲大多數人熟知jQuery、Zepto已經再也不搜索結果的第一頁上了。
由此咱們能夠看出JavaScript的創新性、活躍度和生命力都很是高,不愧爲最流行的語言。
與之相比,Swift就只能基於一種框架進行開發——Cocoa。Swift能夠說是與平臺強相關的,離開蘋果平臺,Swift恐怕沒有用武之地。最近十幾年咱們看到微軟、諾基亞的起起落落。所以在咱們決定是否選擇Swift的時候,咱們對蘋果的前景和信心也是一個重要的考量因素。
以上咱們從語言特性、代碼效率、學習成本和生態環境4各方面考察了Swift。除此之外,還有一些因素值得考慮。
第一個是調試工具。JavaScript做爲一個前臺語言爲何這麼流行?一個重要因素是諸如像Google Chrome和FireFox等工具爲JavaScript提供了至關完善、至關優秀的調試工具。
另一個因素是跨平臺開發。咱們是否願意把本身押寶在一個平臺上,賭這一個平臺的成敗。Php和JavaScript是幾乎沒有平臺的概念。但若是作移動端開發的話,顯然仍是要選擇一個平臺的。不過最近Facebook推出了一個框架:Reactive Native。雖然還不完善,但咱們能夠想象一下,若是咱們能用JS開發iOS,那咱們還會學Swift嗎?
除了開發以外,在實際項目中還有許多工做要作。好比測試,好比對測試結果的分析,對上線後應用運行情況的分析。若是上線後不少用戶出現程序閃退,如何知道閃退緣由?定位問題?
在騰訊內部,有一個公用的crash定位模塊。每一個App均可以使用這個模塊。這個模塊能夠幫助App定位和分析crash的數量、類別、緣由等信息。 如今這個模塊已經對外公佈出來了,名爲Bugly。騰訊以外的App也可使用這個模塊了。
以上咱們對Swift作了多方面的分析和對比。如今能夠回答咱們在本文一開始提出的問題了。
1.咱們是否應該開始學習Swift呢?
結論是確定的。Swift中融合了許多現代語言中先進的特性。經過學習Swift能夠了解現代語言的發展趨勢。多掌握一門語言也有助於橫向對比,更深入的瞭解語言特性的本質,同時也是提升本身的眼界和學習能力的一個高效的手段。
2.個人項目是否應該遷移到Swift?
這個問題要具體狀況具體分析。首先要看團隊的能力。若是團隊的學習能力很強,則能夠考慮使用Swift。可是也不絕對,若是團隊經驗很是豐富,在iOS上面擁有五年以上的開發歷史,那就要慎重一些了,由於這樣會增長學習成本。若是團隊很年輕,經驗也很少則能夠考慮使用Swift。
接下來還要考慮項目的構成。好比包含上千個C語言的文件,那麼轉換的成本就過高了。並且會嚴重影響應用的穩定性。若是是全新的項目,就能夠考慮使用Swift了。
從上面的分析能夠看出,一門語言對項目的影響並無那麼大,對於程序員職業發展的影響也沒有那麼大。
程序員可能有不少發展方向,在這些方向上除了關注語言,開發需求,改Bug,還有不少更重要的事情。在下圖中我列舉了程序員的一些發展方向和對應的關注點。
另外,不管咱們作什麼工做都須要的一些通用能力,好比學習能力,分析和解決問題的能力,創新能力,傳承知識和培養人才的能力,溝通能力等等。
Swift就比如是一套武功招式,它可否發揮巨大威力,不取決於招式自己,而取決於使用者內功。只有本身變強,才能將Swift的特性獲得淋漓盡致的發揮,作出優秀的應用。
因此咱們仍是要關注自身的成長,在Swift的語言以外學習更多的東西。
Bugly是騰訊內部產品質量監控平臺的外發版本,其主要功能是App發佈之後,對用戶側發生的Crash以及卡頓現象進行監控並上報,讓開發同窗能夠第一時間瞭解到App的質量狀況,及時機型修改。目前騰訊內部全部的產品,均在使用其進行線上產品的崩潰監控。