Swift language announcements from WWDC22

在過去的一年里,Swift 有了顯著的發(fā)展,我們已經(jīng)看到了該語言的兩次大更新。Swift 5.6 于 2022 年 3 月發(fā)布,對類型系統(tǒng)、并發(fā)模型和 Swift 生態(tài)系統(tǒng)進(jìn)行了重大改進(jìn)。它為 Swift 5.7 的進(jìn)一步更新奠定了基礎(chǔ),該版本包含在 Xcode 14 的 beta 版本中,可在 Swift.org 下載頁面上找到。
在 WWDC22 期間,許多 Swift 更新得到了適當(dāng)?shù)闹v解,session 重點關(guān)注語言更改、工具改進(jìn)、Swift 包的添加等等。What's new in Swift 視頻很好地概述了過去一年的 Swift 新聞。在這篇文章中,我們想分享來自 WWDC 的關(guān)于 Swift 生態(tài)系統(tǒng)的亮點。
社區(qū)發(fā)展
圍繞 Swift 語言的社區(qū)正在發(fā)展壯大,之前介紹的一些舉措正在擴(kuò)大并獲得更廣泛的支持。已宣布新的工作組將專注于 Swift 生態(tài)系統(tǒng)中的特定領(lǐng)域。Swift 網(wǎng)站工作組正在指導(dǎo) Swift.org 網(wǎng)站的發(fā)展,Swift 和 C++ 互操作性小組正在致力于推進(jìn)兩種語言之間的互操作性支持,而 Swift 語言工作組正在監(jiān)督語言和標(biāo)準(zhǔn)庫。2021 年宣布的 Swift Mentorship Program 已延長一年,并包括其他主題,例如 DocC、C++ 互操作性和 Swift 網(wǎng)站。值得一提的是,Swift.org 網(wǎng)站現(xiàn)已開源,并準(zhǔn)備好接受社區(qū)貢獻(xiàn)。
說到開源,去年宣布的 Swift 框架和包的 Swift-DocC 編譯器現(xiàn)在也開源了,并且有了一些很大的改進(jìn)。它增加了對應(yīng)用程序項目的支持以及對 Objective-C 和 C API 文檔的支持。我們絕對建議您查看 Swift-DocC session 中的新增功能以了解更多信息。
Swift Packages
我們已經(jīng)看到 Swift 包管理器的重要更新,包括對模塊消歧的支持、定義構(gòu)建工具插件和自定義命令插件的能力,以及安全性和性能改進(jìn)。
從 Swift 5.6 開始,Swift Package Manager 執(zhí)行首次使用時的信任 (TOFU) 驗證。首次下載包時會記錄包的指紋,如果指紋不同,后續(xù)下載會報錯。此更改對于更好的包安全性非常有用。
在 Swift 5.7 中,Swift 包管理器獲得了令人興奮的改進(jìn),這將幫助我們避免在項目中使用多個同名包時出現(xiàn)問題。它現(xiàn)在允許我們從定義它們的包之外命名模塊,并添加模塊別名。
使用新的 PackagePlugin API,我們可以定義自定義插件來生成源代碼或自動化發(fā)布任務(wù)。Create Swift Package plugins 課程教我們?nèi)绾卧?Swift 中編寫這樣的插件。
語言更新
今年,我們看到了 Swift 語言的一些重要補(bǔ)充,其中包括一系列變化,從較小的語法改進(jìn)到較大的泛型和并發(fā)更新。
這篇文章重點介紹了在 WWDC 上引起我們注意的一些 Swift 更新。對于以下部分中的代碼示例,我們從新西蘭 Aotearoa 的年度鳥類競賽中獲得靈感。畢竟,考慮到誰是 2021 年年度鳥類的獲勝者(這是一只蝙蝠??),對參賽者來說一些額外的類型安全不會受到傷害。
生活質(zhì)量改善
Swift 5.7 中一個很小但非常好的改進(jìn)是使用 if let、guard let 和 while let 進(jìn)行可選解包的簡寫語法。我們可以刪除右側(cè)以獲取與原始名稱相同的未包裝選項。
var startDate: Date?if let startDate { print("""
Bird of the Year competition \
starts on \(startDate.formatted())
""")
}另一個將改進(jìn)我們的代碼的更改是對具有多個語句的復(fù)雜閉包的類型推斷支持。如果我們的閉包包含 if else、do catch 或任何其他控制流語句,我們不再需要手動指定返回類型。
let participants = ["Kororā", "Weka", "Pekapeka-tou-roa"]let introductions = participants.map { if $0.hasPrefix("Pekapeka") { return "\($0) is a mammal"
} else { return "\($0) is a bird"
}
}字符串處理
Swift 5.7 對字符串處理進(jìn)行了重大更新,引入了正則表達(dá)式文字和 RegexBuilder 庫,并與匹配方法和強(qiáng)類型捕獲配對。
我們可以命名我們的匹配項并輕松地從最終結(jié)果中提取它們。
let intent = "I vote for Pūkeko and Kea"let regex = /I vote for (?<bird1>.+?) and (?<bird2>.+?)/if let votes = try? regex.wholeMatch(in: intent) { print("Your first choice is \(votes.bird1)") print("Your second choice is \(votes.bird2)")
}使用 RegexBuilder,我們可以使用 SwiftUI 風(fēng)格的語言構(gòu)建我們的正則表達(dá)式搜索,這可以使其更具可讀性并解鎖更強(qiáng)大的功能。
let word = OneOrMore(.word)let regex = Regex { "I vote for "
Capture { word } " and "
Capture { word }
}if let votes = try? regex.wholeMatch(in: intent) { let (_, bird1, bird2) = votes.output print("Your first choice is \(bird1)") print("Your second choice is \(bird2)")
}有兩個關(guān)于新字符串處理 API 的信息豐富的 session:Meet Swift Regex 和 Swift Regex: Beyond the basics。
泛型和協(xié)議
今年對 Swift 協(xié)議和泛型有很多改進(jìn)。協(xié)議現(xiàn)在支持主要關(guān)聯(lián)類型。我們可以在協(xié)議名稱旁邊的尖括號中指定它,它應(yīng)該是調(diào)用現(xiàn)場比其他人更頻繁使用的類型。
protocol Contestant<Habitat> {
associatedtype Habitat: Territory
associatedtype Food
var home: Habitat { get set } var favoriteFood: Food { get set } var name: String { get }
}使用尖括號語法,我們可以將主要關(guān)聯(lián)類型約束為特定類型。
func fundReforestation<Animal: Contestant<Forest>>(for animal: Animal) {
scheduleTreePlanting(in: animal.home)
}由于使用一些參數(shù)類型的新能力,編寫泛型方法和函數(shù)也變得更容易。如果泛型參數(shù)只用在一個地方,我們可以指定協(xié)議和一些關(guān)鍵字來表示它的類型,而不需要對函數(shù)設(shè)置泛型約束。
func fundConservationEfforts(for animal: some Contestant) {
establishProtectedAreas(in: animal.home)
startIntensiveMonitoring(of: animal)
}我們甚至可以使用一些具有主要關(guān)聯(lián)類型約束的參數(shù),因此我們可以以更簡潔的方式重寫我們前面的fundReforestation() 函數(shù)示例。
func fundReforestation(for animal: some Contestant<Forest>) {
scheduleTreePlanting(in: animal.home)
}Swift 中的存在類型也有大量改進(jìn)。我們現(xiàn)在可以使用 any 關(guān)鍵字來標(biāo)記使用存在類型的位置,并且我們不再有以前使用具有 Self 或關(guān)聯(lián)類型要求的存在類型的約束。我們可以將它們放入集合中,使用存在類型來約束變量或?qū)⑵溆米鲄?shù)類型。
例如,我們可以創(chuàng)建一個參賽者數(shù)組,這是我們以前無法做到的,因為我們示例中的參賽者協(xié)議具有關(guān)聯(lián)的類型。
let contestants: [any Contestant] = [
brownKiwi, ruru, whio
]for contestant in contestants {
fundConservationEfforts(for: contestant)
}知道之前存在類型的約束已經(jīng)消失,我們可以審核我們現(xiàn)有的類型擦除包裝器的代碼,并檢查我們現(xiàn)在是否可以使用存在類型重新實現(xiàn)它們。
要了解有關(guān) Swift 5.7 中泛型的更多信息,請務(wù)必查看 Embrace Swift generics 這個 session。要了解如何使用協(xié)議設(shè)計高級抽象,請觀看在 Design protocol interfaces in Swift。
并發(fā)
今年的并發(fā)更新建立在去年的變化之上,并專注于數(shù)據(jù)競賽安全。我們甚至在 Xcode 中加入了新的可選安全檢查,以幫助我們識別潛在問題。
去年推出的 Swift Actor 通過隔離對其屬性的訪問來幫助我們編寫線程安全的代碼。今年新的分布式參與者進(jìn)一步采用了參與者隔離的概念,并使開發(fā)分布式系統(tǒng)變得更加簡單。開源分布式 Actors 庫為在 Swift 中構(gòu)建服務(wù)器端集群分布式系統(tǒng)提供了完整的解決方案。Meet distributed actors in Swift 視頻更詳細(xì)地介紹了在使用分布式系統(tǒng)和應(yīng)用程序時使用 actor。
我們還有一個新的 Swift 包 Async Algorithms,它為使用 AsyncSequence 提供了現(xiàn)成的解決方案。它包括我們自己可能難以實現(xiàn)的算法,例如去抖動、節(jié)流、合并和壓縮。這些算法幫助我們隨著時間的推移處理值。
let kiwiFinder = KiwiFinder()let counter = Counter()for try await (i, kiwi) in zip(counter, kiwiFinder) { print("Kiwi number \(i) is a \(kiwi.name)")
}Swift 的另一個重要補(bǔ)充是與時間交互的新標(biāo)準(zhǔn)方式,它包括三個不同的組件:時鐘、瞬間和持續(xù)時間。這些新的 API 與并發(fā)任務(wù)很好地集成在一起。
func announceWinner(_ winner: some Contestant) async throws { print("Building suspense...") try await Task.sleep(
until: .now + .seconds(10),
tolerance: .seconds(1),
clock: .suspending
) print("The winner is \(winner.name)!")
}要了解有關(guān) Async Algorithms 包的更多信息并發(fā)現(xiàn)使用 Swift Clock 類型隨時間處理值的最佳實踐,請查看 Meet Swift Async Algorithms WWDC session。
Swift 中的并發(fā)支持在今年獲得了許多其他重大升級,例如針對提高性能的優(yōu)化、actor 優(yōu)先級和內(nèi)置的優(yōu)先級反轉(zhuǎn)避免。Instruments 現(xiàn)在有一個新的 Swift 并發(fā)模板,可以幫助我們調(diào)查性能問題。可視化和優(yōu)化 Swift 并發(fā)討論討論了我們在應(yīng)用程序中可能遇到的常見問題,并展示了如何使用 Instruments 來查找和解決性能問題。
還有很多很棒的更新,不可能全部覆蓋。由于并行化、使用協(xié)議和 where 子句對函數(shù)簽名進(jìn)行更快的類型檢查、運(yùn)行時協(xié)議一致性檢查的優(yōu)化等,我們在 Xcode 中的構(gòu)建速度越來越快。通過減少標(biāo)準(zhǔn)庫的大小,Swift 可以在各種環(huán)境中運(yùn)行,并且通過簡化的 Linux 工具鏈分發(fā),我們中的更多人可以在我們最喜歡的平臺上享受使用 Swift 的樂趣。
我們非常期待進(jìn)一步探索所有這些新功能并在我們的項目中使用它們。
