歡迎加入QQ討論群258996829
月之殘骸 頭像
蘋果2袋
2
月之殘骸

Swift是花拳繡腿嗎?——談?wù)勯_發(fā)語言與程序員的職業(yè)發(fā)展

發(fā)布時間:2015-07-29 19:02  回復(fù):0  查看:3249   最后回復(fù):2015-07-29 19:02  

隨著WWDC 2015的舉行,Swift 2.0面世,不僅帶來了更多的新特性,更被蘋果寄予厚望,有可能代替Objective-C成為iOS平臺的標(biāo)準(zhǔn)開發(fā)語言。那么Swift能否替代Objective-C成為新的王者?現(xiàn)有的項目是否需要遷移?我們是否應(yīng)該馬上開始學(xué)習(xí)Swift呢?在本問中,筆者將從語法特性,學(xué)習(xí)成本,代碼效率,生態(tài)環(huán)境4個方面入手,對Swift和其他現(xiàn)代語言進(jìn)行分析、對比,共同探討App開發(fā)趨勢和職業(yè)發(fā)展前景。

首先我們考察一下Swift究竟是一個什么樣的變成語言。在2014年蘋果的WWDC(世界開發(fā)者大會)上,Swift首次亮相。蘋果號稱Swift有3大特性:


  • 安全(SAFE)
  • 現(xiàn)代(MODERN)
  • 強(qiáng)大(POWER)


 

安全特性中首先介紹的是變量和常量的類型安全:

例如在下面的代碼中,Swift用關(guān)鍵字let聲明常量,關(guān)鍵字var聲明變量。

 

 

在聲明時可以指定常量和變量的類型,也可以不指定類型,而是直接賦值。Swift會通過所賦值的類型自動將定義變量的類型。

如果聲明時不進(jìn)行賦值,那么每個類型的變量都有自己的默認(rèn)值。

例如Double類型的變量,默認(rèn)值是0。這點與Objective-C、C++和C語言不同,不對變量賦值的話,那么變量的默認(rèn)值是一個隨機(jī)數(shù)。如果不注意這點,則很容易由此導(dǎo)致Bug的產(chǎn)生。使用Swift語言則可以避免這種情況發(fā)生,所以說Swift是類型安全的。

另一個安全特性是在流程控制方面。例如下面代碼中switch語句有2個case語句。分別代表legCount為0和為1至13奇數(shù)的情況。然而顯然除了這兩種情況之外,legCount還可能是其他的值,比如:2或15等等。

 

Swift的語法規(guī)定,如果case語句不能覆蓋所有可能的情況,則必須加default語句來處理其他情況。否則編譯不能通過。

這樣可以避免由于程序員疏忽,流程沒有被switch-case經(jīng)過處理,而引起的邏輯錯誤。

我們可以看到Swift中的安全特性確實有助于新手減少Bug和邏輯錯誤。但是類似于“變量聲明時就有初始值”的特性在JavaScript,C#等多種現(xiàn)代語言中早已實現(xiàn)了。

在功能強(qiáng)大方面,有一個特性中是對字符串操作的簡化,在下面的代碼中,Swfit可以用\(a)的形式,代替C語言中對字符串format操作。大大簡化了代碼,增加了程序的可讀性。

 

無獨有偶,在WWDC2015中,蘋果在新版的Safari和WebKit中增加了一個針對JavaScript的新特性。這個特性可以使用${變量}的符號,代替?zhèn)鹘y(tǒng)的使用“+”對字符串進(jìn)行拼接的操作。

 

在項目實踐中,類似的字符串拼接應(yīng)用較多的是日志操作。一般都已經(jīng)封裝成為組件了。所以,雖然這種語法可以簡化代碼,但對于工程的影響不大。

另一個與功能強(qiáng)大相關(guān)的特性是對Unicode的支持。

例如下面的代碼中可以直接使用蘋果的emoji圖標(biāo)寫程序。每一個小老鼠的圖標(biāo)可以作為一個字符(character)處理。

 

網(wǎng)上還有網(wǎng)友利用Swift的這個特性寫了一個諾亞方舟的故事。

 

另一個強(qiáng)大的功能是For-in語句的增強(qiáng)。

比如在For-in語句中使用0…4表示循環(huán)時取[0,4]的閉區(qū)間內(nèi)整數(shù)值。

 

還可以在For-in中使用“元組”遍歷Dictionary。

 

另外用“n…m”的形式表示[n,m]閉區(qū)間的語法也可以應(yīng)用在switch-case語句中:

 

以上就是蘋果WWDC2014中對Swift功能強(qiáng)大方面的一些介紹。然而,從上面的例子可以看出,這些新特性更像是一些語法糖。語法糖在維基百科上的定義如下:

語法糖(Syntactic sugar),也譯為糖衣語法,指計算機(jī)語言中添加的某種語法,這種語法對語言的功能并沒有影響,但是更方便程序員使用。通常來說使用語法糖能夠增加程序的可讀性,從而減少程序代碼出錯的機(jī)會。


維基百科上除了有語法糖,還有“語法鹽”和“語法糖精”2個概念。分別代表特別難用的語法,和看似很好用但實際有害的語法。 比如在Swift beta版中,在for-in語句中可以使用“n..m”語法,表示從n開始,循環(huán)m次。例如:

 

但是在正式版中,這種寫法被取消了。因為“n..m”和“n…m”這兩種寫法太相似了,如果都保留就會引起混淆,降低程序的可讀性,成為“語法鹽”或者“語法糖精”了。

現(xiàn)在評價Swift中的新語法是語法糖還是語法鹽還為時尚早,需要時間和市場的檢驗。

接下來考察一下Swift中Modern的特性。

首先是閉包。在下面的代碼中,repeat函數(shù)可以接受一個閉包類型的task參數(shù)。在調(diào)用repeat函數(shù)時,傳入的第二個參數(shù)是一個函數(shù)體,其中包含了一行打印語句。

 

那么什么是閉包呢?

閉包有以下3個特點:


  • 匿名函數(shù)(方法);
  • 可以被執(zhí)行;
  • 可以被作為參數(shù)傳遞。


提到閉包,想必很多人都會想到JavaScript。我們就來對比一下JavaScript的閉包。

 

我們可以看到在上述代碼中,sayAlert是閉包,也滿足上述3個特點。

其實滿足上述3個特點的語法還有很多,只是名字不一樣而已。比如Java和C#中的Lamda表達(dá)式:

 

這是一段C#代碼,delegate關(guān)鍵字用于定義一個函數(shù)簽名。比如用del為名稱,定義了一個參數(shù)int返回int的函數(shù)。接下來用Lamada表達(dá)式定義了函數(shù)體為“x =>x * x”表示返回參數(shù)x的平方。

此時myDelegate可以被調(diào)用和傳遞,因此就成為了一個閉包。

更廣義的說,C中的“指向函數(shù)的指針”也滿足上述的3個條件。

因此,閉包雖然是現(xiàn)代語言的特性,但是很多語言都支持,并不能算一個很新穎的特性。

另一個現(xiàn)代的特性是“泛型”。

在Swift中使用泛型很方便,語法和Java、C#、C++也很類似。

 

不過使用Objective-C的朋友也有福了,在即將發(fā)布的XCode7中,Objective-C也支持泛型了。

 

因此我們大可不必因為泛型而轉(zhuǎn)向Swift。

Swift中還有一個特性是“nullable”的變量類型,也叫可選(Optional)變量。

 

這是一個很方便的特性。比如一個返回值為int的函數(shù),可以通過返回nil來表示函數(shù)出錯的情況。而不需要使用NSError,也不需要通過返回某些特殊int值來表示錯誤,比如“-1”或“-IntMax”。

不過類似的語法在10年前的C# 2.0中就出現(xiàn)了。

 

 

以上是微軟官網(wǎng)MSDN上的示例代碼??梢钥吹?,雙問號“??”操作符也是在C#中先出現(xiàn)的。

以上是蘋果WWCD2014中介紹的Swfit 1.0的特性,在今年的WWDC2015中,蘋果發(fā)布了Swift 2.0。其中增加了一個呼聲特別高的特性:通過類似try-catch的語法支持Error處理。

 

通過示例代碼可以看出,Swift支持使用多個catch語句捕獲不同類型的Error,而且也支持使用finally語句。

不過這WWDC 2015大會上PPT中的代碼與微軟官方文檔中的一段代碼非常相似:

介紹了這么多Swift的特性,那么應(yīng)該如何評價Swift語言呢?

從客觀上講,Swift中確實包含了“安全、現(xiàn)代、強(qiáng)大”的特性,但是這些特性在其他語言上早就有支持。因此這些特性與其他語言相比(包括Objective-C)并沒有絕對優(yōu)勢。

對于一個編程語言,除了語言特性之外,還可以從以下3個方面進(jìn)行比較:


  • 代碼效率
  • 學(xué)習(xí)成本
  • 生態(tài)環(huán)境


其中代碼效率又可以分為代碼的“書寫效率”、“編譯效率”和“運(yùn)行效率”。如果與 Objective-C比較,Swift在書寫效率上完勝。

在編譯效率上,由于Swift沒有.h頭文件和一些其他特性,因此比Objective-C在理論上要快。

但是從實際工程上來講,我們內(nèi)部的一個iOS項目,包含了幾千個Objective-C的文件,完全編譯一次需要30分鐘左右。

對于這種情況來說,顯然不能通過遷移到Swift來解決,而是需要重構(gòu)。如果是小型項目,則編譯時間相差就不大了。

對于Swift和Objective-C的運(yùn)行效率,primateLab進(jìn)行了一個對比測試。結(jié)果如下:

 

通過右側(cè)的平均值對比可以看出:


  1. CPU負(fù)荷較大的Mandelbrot的測試中,Swift取得了與C++相近的成績。
  2. GEMM測試中(側(cè)重于大數(shù)據(jù)在有限內(nèi)存中順序讀取操作),Swift與C++差距變大了。
  3. FFT測試中(大數(shù)組隨機(jī)讀?。?,C++取得的成績是Swift的近10倍。


因此可以看出,從運(yùn)行效率上看,Swift不能完全勝任所有的場景。

綜上所述:Swift在代碼效率的3各方面,雖然有一定優(yōu)勢,但是還不能由此得出“我們應(yīng)該轉(zhuǎn)向Swift”的結(jié)論。

我們繼續(xù)從第三個方面:學(xué)習(xí)成本上考察Swift。

Swift雖然屬于類C(C-Family)的語言,在保留了大括號,if-else,do-while,swich-case-default 等語法元素之外,也創(chuàng)新了許多新語法。有些語法形式(比如枚舉類型)變化較大。學(xué)習(xí)Swift語法可能比Objective-C容易一些,但是也不會是零門檻的。

此外使用Swift開發(fā)應(yīng)用必須依賴Cocoa框架,對于之前沒有接觸Cocoa的程序員,這是一塊很大的隱性成本。

這里引用JavaEye社區(qū)創(chuàng)始人Robin的一句話供大家參考:

對程序員來說,熟悉Swift語法也不過一天時間足夠了。關(guān)鍵是要提供高級數(shù)據(jù)類型,簡化Cocoa類庫,否則用不用Swift都沒區(qū)別。

Swift語言的學(xué)習(xí)成本并不像媒體上宣傳得那么低。所以我們還需要從第四個方面——生態(tài)環(huán)境方面進(jìn)行考察。

生態(tài)環(huán)境是一個比較抽象的概念。這里我們把生態(tài)環(huán)境簡化為2個問題:


  1. 是否有很多開源工程可以借鑒?
  2. 有了問題是否能快速找到答案?


對于第一個問題,我們可以參考一下Github上開源項目的統(tǒng)計數(shù)據(jù)( http://githut.info ):

 

Swift雖然在“活躍代碼庫”數(shù)量上比較少,但是在“代碼庫平均分支”數(shù)量和“代碼庫平均關(guān)注者”這兩個指標(biāo)上都處于領(lǐng)先地位。由此可以看出,Swift有一群熱情非常高的愛好者,盡管愛好者絕對數(shù)量可能不多,但是加速的趨勢很大。后續(xù)的發(fā)展是非常值得期待的。

第二個問題“有了問題是否能快速找到答案?”,我們可以參考一下 Stackflow 網(wǎng)站做的一個調(diào)查。其中最流行語言榜單中,與Github一樣,JavaScript排名第一。而Swfit卻沒有入圍。

 

但是在最受歡迎的語言榜單上,Swift排名第一。

 

再次證明程序員對Swift的熱情很高。

綜合上面的兩個問題,可以看出Swift的熱度很高,但是當(dāng)前成熟度還不夠高。我們接下來考察生態(tài)環(huán)境中另一個因素:框架。

我們與最流行的JavaScript對比一下。在Google上搜索“JavaScript framework”,可以看到排名靠前的搜索結(jié)果是關(guān)于JavaScript框架的對比、排名,以及如何選擇框架的文章,對于一個具體框架的介紹排名在第五位。而且為大多數(shù)人熟知jQuery、Zepto已經(jīng)不再搜索結(jié)果的第一頁上了。

由此我們可以看出JavaScript的創(chuàng)新性、活躍度和生命力都非常高,不愧為最流行的語言。

 

與之相比,Swift就只能基于一種框架進(jìn)行開發(fā)——Cocoa。Swift可以說是與平臺強(qiáng)相關(guān)的,離開蘋果平臺,Swift恐怕沒有用武之地。最近十幾年我們看到微軟、諾基亞的起起落落。因此在我們決定是否選擇Swift的時候,我們對蘋果的前景和信心也是一個重要的考量因素。

以上我們從語言特性、代碼效率、學(xué)習(xí)成本和生態(tài)環(huán)境4各方面考察了Swift。除此以外,還有一些因素值得考慮。

第一個是調(diào)試工具。JavaScript作為一個前臺語言為什么這么流行?一個重要因素是諸如像Google Chrome和FireFox等工具為JavaScript提供了相當(dāng)完善、相當(dāng)優(yōu)秀的調(diào)試工具。

另外一個因素是跨平臺開發(fā)。我們是否愿意把自己押寶在一個平臺上,賭這一個平臺的成敗。Php和JavaScript是幾乎沒有平臺的概念。但如果做移動端開發(fā)的話,顯然還是要選擇一個平臺的。不過最近Facebook推出了一個框架:Reactive Native。雖然還不完善,但我們可以想象一下,如果我們能用JS開發(fā)iOS,那我們還會學(xué)Swift嗎?

除了開發(fā)之外,在實際項目中還有許多工作要做。比如測試,比如對測試結(jié)果的分析,對上線后應(yīng)用運(yùn)行狀況的分析。如果上線后很多用戶出現(xiàn)程序閃退,如何知道閃退原因?定位問題?

在騰訊內(nèi)部,有一個公用的crash定位模塊。每個App都可以使用這個模塊。這個模塊可以幫助App定位和分析crash的數(shù)量、類別、原因等信息。 現(xiàn)在這個模塊已經(jīng)對外公布出來了,名為Bugly。騰訊之外的App也可以使用這個模塊了。

以上我們對Swift做了多方面的分析和對比?,F(xiàn)在可以回答我們在本文一開始提出的問題了。


  • 我們是否應(yīng)該開始學(xué)習(xí)Swift呢?


答案是肯定的。Swift中融合了許多現(xiàn)代語言中先進(jìn)的特性。通過學(xué)習(xí)Swift可以了解現(xiàn)代語言的發(fā)展趨勢。多掌握一門語言也有助于橫向?qū)Ρ?,更深刻的了解語言特性的本質(zhì),同時也是提高自己的眼界和學(xué)習(xí)能力的一個高效的手段。


  • 我的項目是否應(yīng)該遷移到Swift?


這個問題要具體情況具體分析。首先要看團(tuán)隊的能力。如果團(tuán)隊的學(xué)習(xí)能力很強(qiáng),則可以考慮使用Swift。但是也不絕對,如果團(tuán)隊經(jīng)驗非常豐富,在iOS上面擁有五年以上的開發(fā)歷史,那就要慎重一些了,因為這樣會增加學(xué)習(xí)成本。如果團(tuán)隊很年輕,經(jīng)驗也不多則可以考慮使用Swift。

接下來還要考慮項目的構(gòu)成。比如包含上千個C語言的文件,那么轉(zhuǎn)換的成本就太高了。而且會嚴(yán)重影響應(yīng)用的穩(wěn)定性。如果是全新的項目,就可以考慮使用Swift了。

從上面的分析可以看出,一門語言對項目的影響并沒有那么大,對于程序員職業(yè)發(fā)展的影響也沒有那么大。

程序員可能有很多發(fā)展方向,在這些方向上除了關(guān)注語言,開發(fā)需求,改Bug,還有很多更重要的事情。在下圖中我列舉了程序員的一些發(fā)展方向和對應(yīng)的關(guān)注點。

 

另外,無論我們做什么工作都需要的一些通用能力,比如學(xué)習(xí)能力,分析和解決問題的能力,創(chuàng)新能力,傳承知識和培養(yǎng)人才的能力,溝通能力等等。 


  • Swift是花拳繡腿嗎?


Swift就好比是一套武功招式,它能否發(fā)揮巨大威力,不取決于招式本身,而取決于使用者內(nèi)功。只有自己變強(qiáng),才能將Swift的特性得到淋漓盡致的發(fā)揮,做出優(yōu)秀的應(yīng)用。

所以我們還是要關(guān)注自身的成長,在Swift的語言之外學(xué)習(xí)更多的東西。



作者簡介:

任旻,北京工業(yè)大學(xué)碩士, 2005年加入微軟中國有限公司,2009年加入騰訊,現(xiàn)任高級工程師,曾負(fù)責(zé)開發(fā)“QQ概念版”、“Q+”、"QQ互聯(lián)”、“iPad QQ”等產(chǎn)品。騰訊學(xué)院講師,專利達(dá)人。一直從事互聯(lián)網(wǎng)領(lǐng)域軟件開發(fā)和生態(tài)系統(tǒng)建設(shè)等工作。



您還未登錄,請先登錄

熱門帖子

最新帖子

?