1. 程式人生 > >【絕對乾貨】Swift是花拳繡腿嗎?從Swift談開發語言與程式設計師的職業發展

【絕對乾貨】Swift是花拳繡腿嗎?從Swift談開發語言與程式設計師的職業發展

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

  • 安全(SAFE)
  • 現代(MODERN)
  • 強大(POWER)

 

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

例如在下面的程式碼中,Swift用關鍵字let宣告常量,關鍵字var宣告變數。

 

 

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

如果宣告時不進行賦值,那麼每個型別的變數都有自己的預設值。

例如Double型別的變數,預設值是0。這點與Objective-C、C++和C語言不同,不對變數賦值的話,那麼變數的預設值是一個隨機數。如果不注意這點,則很容易由此導致Bug的產生。使用Swift語言則可以避免這種情況發生,所以說Swift是型別安全的。

另一個安全特性是在流程控制方面。例如下面程式碼中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的新特性。這個特性可以使用${變數}的符號,代替傳統的使用“+”對字串進行拼接的操作。

 

在專案實踐中,類似的字串拼接應用較多的是日誌操作。一般都已經封裝成為元件了。所以,雖然這種語法可以簡化程式碼,但對於工程的影響不大。

另一個與功能強大相關的特性是對Unicode的支援。

例如下面的程式碼中可以直接使用蘋果的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中的新語法是語法糖還是語法鹽還為時尚早,需要時間和市場的檢驗。

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

首先是閉包。在下面的程式碼中,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進行了一個對比測試。結果如下:

 

通過右側的平均值對比可以看出:

  1. CPU負荷較大的Mandelbrot的測試中,Swift取得了與C++相近的成績。
  2. GEMM測試中(側重於大資料在有限記憶體中順序讀取操作),Swift與C++差距變大了。
  3. FFT測試中(大陣列隨機讀取),C++取得的成績是Swift的近10倍。

因此可以看出,從執行效率上看,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個問題:

  1. 是否有很多開源工程可以借鑑?
  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做了多方面的分析和對比。現在可以回答我們在本文一開始提出的問題了。

  • 我們是否應該開始學習Swift呢?

答案是肯定的。Swift中融合了許多現代語言中先進的特性。通過學習Swift可以瞭解現代語言的發展趨勢。多掌握一門語言也有助於橫向對比,更深刻的瞭解語言特性的本質,同時也是提高自己的眼界和學習能力的一個高效的手段。

  • 我的專案是否應該遷移到Swift?

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

接下來還要考慮專案的構成。比如包含上千個C語言的檔案,那麼轉換的成本就太高了。而且會嚴重影響應用的穩定性。如果是全新的專案,就可以考慮使用Swift了。

從上面的分析可以看出,一門語言對專案的影響並沒有那麼大,對於程式設計師職業發展的影響也沒有那麼大。

程式設計師可能有很多發展方向,在這些方向上除了關注語言,開發需求,改Bug,還有很多更重要的事情。在下圖中我列舉了程式設計師的一些發展方向和對應的關注點。

 

另外,無論我們做什麼工作都需要的一些通用能力,比如學習能力,分析和解決問題的能力,創新能力,傳承知識和培養人才的能力,溝通能力等等。 

  • Swift是花拳繡腿嗎?

Swift就好比是一套武功招式,它能否發揮巨大威力,不取決於招式本身,而取決於使用者內功。只有自己變強,才能將Swift的特性得到淋漓盡致的發揮,做出優秀的應用。

所以我們還是要關注自身的成長,在Swift的語言之外學習更多的東西。



作者簡介:

任旻,北京工業大學碩士, 2005年加入微軟中國有限公司,2009年加入騰訊,現任高階工程師,曾負責開發“QQ概念版”、“Q+”、"QQ互聯”、“iPad QQ”等產品。騰訊學院講師,專利達人。一直從事網際網路領域軟體開發和生態系統建設等工作。