Swift 5.3的進化:語法、標準庫、除錯能力大幅提升

阿里巴巴淘系技術發表於2020-08-11

概括

Swift 從 5.0 的 ABI 穩定到5.1 的模組穩定,Swift 終於不是《Swift 入門到重學》了。本次 WWDC2020,Swift 5.3 正式釋出,Swift 依舊朝著安全、高效、易讀的方向持續發力,不斷的在改進語法,增強程式碼的表達能力和易用性。因為 Swift 的模組穩定,SPM 現在也支援了二進位制模組的分發,逐漸完善的社群生態也在不斷拓寬 Swift 可以涉足的領域,而不僅僅是在 Apple 平臺之上。

下圖展示了 WWDC2020 中 Swift 相關內容的腦圖,希望可以幫助大家快速瞭解。

image.png

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

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

語言環境的完善和擴充

一門完善程式語言有三個最基本的要素:語法、標準庫、除錯能力。語法設計決定了語言的程式設計正規化;標準庫決定了語言的基本能力;除錯能力決定了開發者的體驗和語言的穩定性。

蘋果在 Swift 的迭代過程中不斷的強化這幾點,我們可以來看看 Swift 又得到了哪些提升。

語法特性

Swift 的語法設計核心還是 OOP,但是這不妨礙 Swift 的語法在支援 POP 和函數語言程式設計甚至 DSL 得到的強化。Swift 也因為 SDL 特性的加入,開始逐漸的適應宣告式程式設計的方向發展,比如後文提到的 @main 等等。

Multiple trailing closure

image.png

這個改進解決了當函式最後幾個引數為閉包的情況下,導致的括號巢狀的問題,API 更加簡潔也更加具有表達性。SwiftUI 利用這個語言特性,也變得更加簡潔易懂。

KeyPath as Function

image

現在 KeyPath 可以當做函式來使用了。這個語法糖解決的問題當我們使用類似 map 一樣的函式時,只需要取出對應資料模型中的某一個屬性,為此我們不得不寫類似 map { $0.property } 的程式碼,有了這個語法糖,事情就可以簡化成了 map(\.property)

Type-based program entry point (@main)

引入了新的修飾符 @main,可以標記在帶有 public static func main() 函式實現的所有型別,無論 main 函式時從擴充來得還是繼承來的。新增這個特性的意義在與維持宣告式的語義,將宣告式語義進行到底。YES!


Increase availability of implicit self in closures

以前我們寫逃逸閉包時如果捕獲了 self,我們需要在跟 self 有關的地方寫上 self. 以警示我們注意迴圈引用。

image.png

如果在閉包的捕獲列表中顯示宣告捕獲 self,在閉包中對 self 相關的訪問可以省略。如果是在不可變的函式中訪問,self 可以直接省略(為了 SwiftUI)。

image.png

其實這一點改進有用但是覆蓋面並不是很廣,因為在實際的應用中,我們都是儘量先弱引用 self 後再強引用 self,來保證 self 的可訪問性。在如下場景就得不到此項優化:

image

Multi-pattern catch clauses

這種寫法可以自動實現錯誤匹配,進入到對應的錯誤處理中,而不需要使用 switch,增強語言的可讀性。

image.png

Enum enhancements

自動符合 Comparable

編譯器現在可以自動為你生成 Comparable 的相關方法,實現 Enum 的比較。

image.png

Enum case 可以用來適配 protocol

這個特性看引用場景需要吧,官方給了一個比較好的例子。具體相關內容可以參考 SE-0280。

image.png

DSL 新增對 switch 的支援

現在可以在 SwiftUI 等 Swift DSL 中使用 switch-case 來進行模式匹配,之前只有對 if-else 的支援。某種程度上也是為 SwiftUI 而生的能力。

image.png

標準庫

其實這裡說標準庫是廣義的標準庫,其中包括了開發者隨語言分發的標準庫,如標準 I/O 庫等,執行時環境,編譯環境,一方庫等等。蘋果今年在這部分下足了功夫,因為標準庫、各種各樣的一方三方庫才是展現一門語言能力的地方,否則再好的語法也不會有人用,語言終究還是工具,能解決問題才是關鍵。

Swift 5.3 在程式碼尺寸和執行時都有不小的提升。Swift Package Manager(SPM)增加對二進位制和資源的支援,深度整合 Xcode,親兒子的優勢逐漸顯示了出來。Swift 本來設計的初衷本來就是一門 General Purpose 的語言,今年蘋果正式宣佈 Swift 支援了 Apple platform,Ubuntu/CentOS/Amazon Linux,不久的將來也會支援 Windows,正式成為一門優秀的跨平臺語言。

標準庫更新

  • Float16 的支援,具有更好的運算效能
  • Apple Archive 一種功能類似 zip 的壓縮檔案,蘋果就是用這種格式來更新系統
  • Swift System 對作業系統基礎 API 的包裝,讓 API 更健壯易用
  • OSLog 推薦使用的 logging system

從這些更新可以看出,蘋果對 Swift 的底層操作非常關心,Swift System 的出現讓使用 Swift 底層開發者脫離 OS C API 的折磨,獲得更一致更健壯的程式碼體驗。

新的一方庫

Code Size and Runtime

在使用 UIKit 的情況下,Swift 4.1 時生成的二進位制程式碼已經從 OC 的兩倍還多,但是在 Swift 5.3 中,這個差距已經縮小到小於 1.5 倍了。也就是說之前大量使用 Swift app 會自動得到二進位制大小的優化,而對於擔憂 Swift 會造成包大小問題的 App,現在已經不算是很大的問題了。因為只需要付出可以接受的代價,就能獲得 Swift 帶來的安全效能和開發體驗。

image.png

如果 App 使用了純 SwiftUI,二進位制程式碼甚至可以縮小 43% 之多。可見蘋果優化 Swift 的功底之深,而且這些優化,只需要從新編譯一次即可享受,何樂而不為。

image.png

因為 Swift 更緊湊的值型別,執行時的記憶體,分配相同的物件所需的空間自然比 OC 更小。Swift 5.3 相較 5.1,執行時的必要額外資訊儲存要少非常多,甚至做到了比 OC 還要少,大大減小了 Swift 的執行時記憶體。這對低記憶體的裝置是非常有幫助的,同時,更少的系統記憶體意味著更多的使用者記憶體。而這一切,只需要重新編譯即可。

image.png

Swift 底層的不斷優化也讓其成為一門高效的語言,降低執行時的要求,就可以提升其應用的場景。

Swift Package Manager

SPM 作為 Swift 生態非常重要的一環,也迎來了更新。

  • SPM 支援二進位制包分發
  • SPM 支援了資源的打包

這兩點更新已經表明了 SPM 的能力已經足夠完善了。目前具有一定規模 App 的內部模組都開始使用 Cocoapods 做二進位制元件化的整合,這樣可以明確對程式碼解耦,提高打包的效率。在這樣的背景之下,SPM 對這兩點關鍵特性的支援已經可以覆蓋住大型 App 需求了,而且 SPM 不單單隻跟 Swift 玩,C Family 它都可以支援。

在 SPM 與 Cocoapods 的對比中,親兒子 SPM 跟 Xcode 深入整合,Xcode 可以直接開啟編輯 swift package,Xcode 因為 SPM 設計了對應的操作介面,降低了開發和使用的門檻。成熟的工具鏈也讓聯調 Swift Package 輕而易舉。而 Cocoapods 由社群維護,每一次 Xcode 更新其響應也不算很及時,在針對大型 App 時因為 Podfile 與 podspec 的分離導致了許多不一致,使用 ruby 還有一定的門檻。

現在也許是擁抱 SPM 的好時機。

跨平臺

現在官方支援的作業系統列表如下:

  • Apple platform
  • Ubuntu 16.04, 18.04, 20.04
  • CentOS 8
  • Amazon Linux 2
  • Windows (coming soon)

真正做到的跨平臺,並且 Swift 官方支援 AWS Lambda。AWS Lambda Runtime 已經開源,支援了 AWS 的 FaaS 程式設計,進一步的拓寬了 Swift 涉足的領域。

除錯能力(開發者體驗)

除錯和開發者體驗也是一門語言非常重要的一環,因為沒有人會寫出沒有錯誤的程式碼,檢查錯誤的能力和工具對一門語言來說十分重要。蘋果也十分注重這一方面,在開發者體驗上下足了功夫。

更加智慧的診斷資訊

剛開始使用 Swift 的開發者可能經常會對 Xcode 的報錯資訊不知所云,在引入 SwiftUI 後,這個問題尤為明顯。筆者第一次編寫 SwiftUI 時,只要 body 中某個地方出錯,報出來的錯誤都是不正確的,只能通過肉眼檢查和推斷才能明白自己的錯誤,十分痛苦。

現在蘋果重製了診斷能力,現在 Swift 的錯誤診斷比之前準確了許多,錯誤沒有亂報並且錯誤提示也變得很好理解,特別是 SwiftUI,很容易知道錯在哪了。在 Swift 中,編譯通過就是對正確性的一個很好的證明,除非你用不安全的方式讓編譯器閉嘴。

自動補全

經過強化的型別推斷系統,也增強了 Swift 的程式碼補全能力。這個估計升級到 Xcode 12 就可以順利體驗了。同時程式碼縮排能力也得到了加強。

LLDB

image.png

積極擁抱 Swift

看了這麼多年 WWDC,每次看時大家應該都有一種心態

只支援最新版本,我們才支援 iOS X (低版本),這些東西跟我沒關係

感覺 Swift 真香,但是現實只讓我使用 OC(嘆口氣)

什麼語言不是用,OC 這麼多年肯定夠用了

危機

然而如果不及時做出改變,保持能用就行,在前進的路上,背上的擔子就會越來越重。當發現快走不動時,又回過頭來看 WWDC,就會發現,原來解決方案很久以前就已經給出來了,只是當時不覺得是個問題,這不支援那不合適,但是現在想拿出來使用的時候,面對背上那一團團的亂碼,卻又束手無策。

做出改變是痛苦的,但是當以前覺得癢就撓撓就解決了的事情,逐漸變成現在的痛點時,要做出改變也許會更痛苦。

Swift 的出現就是為了替代並且超越 Objective-C 的語言,雖然說蘋果因為歷史原因還在使用 OC,但是種種跡象表明,蘋果正在做積極的工作,逐漸通過 Swift 降低 OC 在整個系統的比重。

社群也在積極的轉變,許多著名的第三方庫都已經遷移至 Swift,OC 版本已經不再維護,例如 Lottie 已經在 Swift 版本上出現了 OC 版本不存在的特性,並且 OC 版本不再維護。這種現象慢慢會越來越多。

改變

我們也在積極探索 Swift 在手淘的落地,取得了 Swift 5.1 能模組在手淘中正確執行起來的階段性成就。

現在時機已經成熟,語言特性,SPM,工具鏈,標準庫都已經足夠強大,是時候做出改變了。

Swift 雖然看起來很簡單,但其實它是一種下限低,上限高的語言,集團內部的 Swift 環境,需要大家來一起維護。我們未來也要加強 Swift 語言相關的培訓,讓開發者真正理解 Swift,上手 Swift,成為一名 Swifter 而不是 OSwifter。

手淘客戶端團隊正在進行社招招聘,崗位有iOS Android客戶端開發工程師等,歡迎推薦。

簡歷投遞:junzhan.yzw@taobao.com

參考

  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

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

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

相關文章