Swift 5.3 又更新了什麼新奇爽快的語法?

阿里巴巴淘系技術發表於2020-07-21

Swift 發展里程碑

Swift 在 WWDC14 正式釋出到 2019,經過 5 年的不斷迭代,這其中經歷了標準庫變動,語法的增減。首先使用 Swift 作為開發語言的開發者們都苦不堪言,戲稱《Swift 從入門到重學》,幾乎每一年 Swift 都會迎來比較大的改動,甚至 API 都發生了變化。

WWDC 19 蘋果釋出了 Swift 5.0,蘋果終於宣佈 Swift 的 ABI 穩定。這標誌著 Swift 這門語言已經趨於穩定,在 2019 至 2020 的迭代中,Swift 5.2 也做到了模組穩定,之前的大修大改已經不會在出現了。

image.png

有意思的是,在 WWDC16 中有一頁 PPT 寫下了 Goals for Swift 3:

  • Develop an open community
  • Portability to new platforms
  • Get the fundamentals right
  • Optimize for awesomenss

如今已經 2020 年,再回頭看這些目標,Swift 5.3 幾乎完全實現了。Swift 可謂一直不忘初心,朝著認為正確的方向不斷的努力。

( WWDC 2020精彩內容思否專欄:https://segmentfault.com/blog...  

本篇內容來自於阿里巴巴淘系技術部,無線開發工程師星志。
更多精彩內容可關注【淘系技術】公眾號。)

語法的不斷成熟

每年 WWDC 比較期待的一個點就是看看 Swift 又加了一些什麼新奇爽快的語法。我先列舉一下 Swift 5.3 新增的語法:

  • [SE-0249] KeyPath as Function
  • [SE-0279] Multiple trailing closure
  • [SE-0281] Type-based program entry point (@main))
  • [SE-0266] Synthesized comparable conformation for enum types
  • [SE-0269] Increased availability of implicit self in closure
  • [SE-0276] Multi-pattern catch clauses
  • [SE-0280] Enum cases as protocol witnesses
  • [SE-0267] Where clauses on contextually generic declarations
  • [SE-0270] Collection operations on noncontiguous elements
  • [SE-0264] Standard library preview package
  • [SE-0253] Callable values of user-defined nominal types
  • [SE-0263] String initializer with access to uninitialized storage

上面列舉的 12 個語法改動,有興趣的同學可以到 swift-evolution 去檢視詳細的內容。其中比較有意思的幾個改動就是 [SE-279],[SE-281]和[SE-0269],我們來細細評味一下。

Design for SwiftUI

[SE-279] Multiple trailing closure 多重尾閉包這個新特性算是一個非常大的改動。這個特性的出現影響了 Swift 非常重要的地方,API 設計。先來幾個官方的例子:

螢幕快照 2020-07-21 下午3.36.44.png

上面的程式碼中 2 的情況是經常出現的,尾閉包的含義就不夠明確,以前最佳的方式應該為 3,但是兩個閉包被套在一個小括號裡,使得括號多重巢狀,可讀性下降。為了解決這個問題,蘋果使用了第 4 中方法--多重尾閉包。可以從程式碼看出可讀性得到了很大的提升。

這一看似優雅的設計其實引入了很多語言的複雜度,有了這個特性你甚至可以寫出類似下面的程式碼,看上去就像是創造了一個 if-else 語句,但其實它是一個函式。

螢幕快照 2020-07-21 下午3.49.07.png

這就對 SDK 的開發者提出了更高的要求,需要小心的使用這個特性來設計 API,防止這個特性被濫用導致程式碼的可讀性下降,甚至造成歧義。蘋果在 WWDC20 中也強調了這一點。

還有兩個特性其實很簡單,[SE-0281] 是 @main 來標記程式入口,[SE-0269] 是讓開發者在特定的情況下不需要再寫多餘的 self.

蘋果推出了這幾個語言特性,就是為了讓戰略性的專案 SwiftUI 的 API 更加簡潔明瞭。可以看下面的例子:

螢幕快照 2020-07-21 下午3.49.44.png

蘋果也不是第一次為了 SwiftUI 改 Swift 的語法,[SE-0255] Implicit returns from single-expression functions 就是為了讓 SwiftUI 的 body 不用寫 return,強化 DSL 風格。

蘋果為了 SwiftUI,推出了 functionBuilder 來實現 DSL 形式的程式碼;為了 SwiftUI,推出了許多讓它更漂亮的語法特性;為了 SwiftUI,不惜為語言引入更多的複雜度。

下限低,上限高

Swift 的最初的設計方向就導致了它是一門下限很低上限很高,入門容易精通難,使用容易設計難的語言。它一系列的語法糖和語法設計,包括型別推斷系統,都是讓它成為十分親民的語言,而它的一系列語法特性,讓它在設計 API、SDK實現的時候其複雜程度也不亞於其他語言。

Swift is a general-purpose, multi-paradigm, compiled programming language developed by Apple Inc. for iOS, iPadOS, macOS, watchOS, tvOS, and Linux.

---- Wikipedia

維基百科的後半部分可能有些侷限了,但是前半部分說明了它是一門多程式設計正規化的語言,Swift 可以支援 物件導向程式設計(OOP),面向協議程式設計(OPP),宣告式程式設計(DP),函數語言程式設計(FP),泛型程式設計(GP)。

Objective-C 已經發展了這麼多年,如此成熟,為什麼現在蘋果要開始拋開它?Objective-C 本來就是生於一個物件導向程式設計正規化起飛的一年,與 C++ 一樣為了擴充 C 指令式程式設計正規化而誕生的語言。當時 C 語言雖然也可以實現 OOP,但是語法設計成為了限制。在當代計算機程式語言研究演進下,出現了很多程式設計正規化的新理論,如函數語言程式設計,超程式設計等等,同樣 OC 可以通過它的方式來實現,但是語言的冗雜和 OOP 的設計已經不能更好的表達這些概念,就猶如純 C 來表達OOP 一樣。

蘋果推出 Swift 就是為了擺脫 OC 的束縛,讓它能更好的踐行現代的程式設計理論,所以才會誕生出 SwiftUI,才會有 Combine、map/filter/reduce 等這些庫和 API。型別推斷和超程式設計的理論也讓 Swift 在保留強型別的環境下還能保持如此簡潔優雅,可讀性強的程式碼。而這些是 OC 無法做到的。嘗試使用 OC 對這些現代概念做表達的 SDK 都會顯得十分冗雜。

現在 Swift 語法已經不會再大變,有如此現代、安全、穩定、富有想象力的語言,有什麼理由不真香呢?

土壤已經肥沃

我們先通過下面的腦圖感受一下 Swift 更迭到 5.3 已經取得的成就。

image.png

現在 Swift 生態環境已經自成一派,有一套完整的工具鏈保證開發,有更獨立的標準庫讓它可以自由遷移,包管理讓豐富了它的 SDK,同時還具有 Native 語言的各種優勢。在這麼多年的發展中,它的能力已經觸及到了 AI、Server、Mobile Device、FaaS,強大的標準庫讓它甚至可以當指令碼語言使用。

Swift 如今已經不再孤立無援,開源讓 Swift 變得生機勃勃,合理優雅的設計和開放的態度讓全球的開發者們都在不斷的完善它。

在 Swift 的大生態中,包管理工具是最值得一說的。一門語言它的能力,取決於它是否有強有力的 SDK,還有就是獲取他們的途徑。基礎的 Swift 的能力都由工具鏈和標準庫提供,而強有力的 SDK 最好的方式就是通過包管理工具快速獲取。Swift Package Manager 就是 Swift 的軍械庫。

Swift Package Manager

看一下 Swift Package Manager(SPM) 的發展歷程,SPM 從 Swift 3.0 時就釋出,當時只支援 Git 遠端倉庫,支援支原始碼釋出。WWDC 19,Xcode 引入了一個新的架構 XCFramework,一個旨在能打包多個平臺 framework 的檔案結構。WWDC20 SPM 宣佈正式支援釋出二進位制 framework。

WWDC20 SPM 走出的這一步標誌著功能的完善。為什麼這麼說,因為在 iOS 屆,解決了 Xcode 無包管理工具難題,讓眾多優秀的開源庫能被快速獲取的包管理工具 -- Cocoapods。在 SPM 出現之前,Cocoapods 的功能已經非常完善,打敗了當時另外的一款包管理工具 Carthage。

Cocoapods 作為基於 Xcode 開發的第三方包管理工具,通過修改 Xcode 的工程資訊來實現處理各個包的依賴問題。它支援依賴的二進位制分發、原始碼分發,基於 framework 良好的資源管理。現在許多公司的大型 App 也是用 Cocoapods 做模組化元件分離,通過二進位制依賴的方式來提高打包速度。

然而比較可惜的是它工作流是脫離 Xcode 的,Podfile 更新等操作都是在工程之外。語言使用的是 Ruby,雖然使用了一些操作使 Podfile 變成了 DSL,但是對於開發者而言是有一定門檻的,特別是需要編輯釋出 SDK 所使用的 podspec 時,對照文件,無程式碼提示的編寫讓寫正確配置檔案都成了難事。Cocoapods 還不得不設計出 podspec lint 來幫組開發者確認這個事情。

對於 Swift PM 這個親兒子而言,就不存在這個問題,SPM 已經深入的整合到了 Xcode 中,所有的操作都可以利用 Xcode 完成。在編寫 Swift Package 時,Xcode 現在已經具備將 Package.swift 作為工程專案開啟,並且現在工程模板中已經包含了 Swift Package。強大的 Xcode 自動補全讓編寫 Package.swift 不再是一件難事。如果脫離 Xcode,利用 swift-lsp 結合現在熱門的文字編輯器,如 VSCode 等都可以實現相應的功能。SPM 現在已經是獨立於 Xcode 的存在,可以為 Swift 提供強有力的支援。

SPM 在功能層面已經不遜於 Cocoapods,在 WWDC20 時,SPM 已經支援以二進位制庫形式分發 Package,SPM 也可以管理包中的資源和本地化,基本的能力已經與 Cocoapods 差異不大,然而最關鍵的是,SPM 是純 Swift ,開源,還有蘋果官方支援的包管理工具。

新瓶釀酒酒更香

國外的不少 APP 已經遷移到了 Swift;三方開源庫如 AFNetworking 已經用 Swift 重寫為 Alamofire,Lottie 已經完全被 Swift 重寫替代。蘋果也推出了許多 Swift Only 的庫。蘋果也在利用 Swift 為 UIKit,GCD 等基礎庫不斷提供更具有表現力的 API。

Uber 完成了遷移,收穫了 Swift 極強的穩定性。Alamofire,SnapKit 用  Swift 重寫,獲得了更加具有表現力的 API,開發者更容易接受且喜愛。 Reactive 系列的程式設計風格在 Swift 上大放異彩。

機會與展望

現在 Swift 發展了這麼多年,遍地開花,Objective-C 已經有在逐漸被廢棄的趨勢。現在很有可能都很難招到認真學習過 OC 的應屆生了。

Swift 在集團內部的發展,還有很多的工作要做,這其中充滿了挑戰。我們也在積極探索 Swift 在手淘的落地,取得了 Swift 5.1 能模組在手淘中正確執行起來的階段性成就。但是比較遺憾的是還有很多模組是無法讓 Swift 正確跑起來的,以現在的工具鏈來說甚至原始碼依賴除錯都無法做到。

但是這都是暫時的,現在時機已經成熟,Swift的語言特性,SPM,工具鏈,標準庫都已經足夠強大。未來,我們會盡快大力升級 Swift 的基建。讓 Swift 的花在集團內開起。先定個小目標,希望 Swift 能成為集團 iOS 客戶端開發的首選語言。

( WWDC 2020精彩內容思否專欄:https://segmentfault.com/blog...  

本篇內容來自於阿里巴巴淘系技術部,無線開發工程師星志。
更多精彩內容可關注【淘系技術】公眾號。)

參考

  1. SwiftUI 背後那些事兒
  2. WWDC20 What's new in Swift
  3. WWDC19 What's new in Swift
  4. WWDC18 What's new in Swift
  5. WWDC17 What's new in Swift
  6. WWDC16 What's new in Swift)
  7. WWDC20 Swift packages: Resources and localization
  8. WWDC20 What's new in SwiftUI
  9. Swift 5 時代的機遇與挑戰到底在哪裡?
  10. Swift Evolution

淘寶基礎平臺團隊正在進行社招招聘,崗位有iOS Android客戶端開發工程師、歡迎 轉崗推薦, 簡歷投遞:junzhan.yzw@taobao.com

相關文章