本篇主要是對(duì)《A站 的 Swift 實(shí)踐》文章中的一幅配圖做了詳細(xì)的擴(kuò)展,能夠更加全面和詳細(xì)了解 Swift 語(yǔ)言的發(fā)展,文章中提到的 Swift 各版本的語(yǔ)法示例代碼,及本文內(nèi)容都可以在 戴銘的小冊(cè)子里對(duì)應(yīng)欄目里找到,這個(gè)假期我也對(duì)小冊(cè)子里欄目?jī)?nèi)容進(jìn)行了些更新和補(bǔ)充。《A站 的 Swift 實(shí)踐》文章的那個(gè)演進(jìn)配圖如下:
文章內(nèi)容如下:
Swift 1.1
- countElements() 改成了 count()。
- @NSApplicationMain 可以在 macOS 上使用。
Swift 1.2
- 引入 Set 類(lèi)型。
- if let 可以放到一起,使用逗號(hào)分隔。
- 新增 zip() 和 flatMap()。
- 類(lèi)增加靜態(tài)方法和靜態(tài)屬性,使用 static 關(guān)鍵字描述。
- as! 用于類(lèi)型強(qiáng)轉(zhuǎn),失敗會(huì)崩潰。
- @noescape 用于描述作為參數(shù)閉包,用來(lái)告訴 Swift 閉包將在函數(shù)返回前使用。
- 常量可以延后初始化。
Swift 2.0
- 增加 guard 關(guān)鍵字,用于解可選項(xiàng)值。
- defer 關(guān)鍵字用來(lái)延遲執(zhí)行,即使拋出錯(cuò)誤了都會(huì)在最后執(zhí)行。
- ErrorType 協(xié)議,以及 throws、do、try 和 catch 的引入用來(lái)處理錯(cuò)誤。
- characters 加上 count,用來(lái)替代 count()。
- 用 #available 用來(lái)檢查系統(tǒng)版本。
Swift 2.1
- 字符串插值可以包含字符串字面符號(hào)。
Swift 2.2
- FILE, LINE 和 FUNCTION 換成 #file,#line 和 #function。
- 廢棄 ++ 和 -- 操作符。
- C 語(yǔ)言風(fēng)格 for 循環(huán)廢棄。
- 廢棄變量參數(shù),因?yàn)樽兞繀?shù)容易和 inout 搞混。
- 廢棄字符串化的選擇器,選擇器不再能寫(xiě)成字符串了。
- 元組可直接比較是否相等。
Swift 3.0
- 規(guī)范動(dòng)詞和名詞來(lái)命名。
- 去掉 NS 前綴。
- 方法名描述參數(shù)部分變?yōu)閰?shù)名。
- 省略沒(méi)必要的單詞,命名做了簡(jiǎn)化呢。比如 stringByTrimmingCharactersInSet 就換成了 trimmingCharacters。
- 枚舉的屬性使用小寫(xiě)開(kāi)頭。
- 引入 C 函數(shù)的屬性。
Swift 3.1
- 序列新增 prefix(while:) 和 drop(while:) 方法,順序遍歷執(zhí)行閉包里的邏輯判斷,滿足條件就返回,遇到不匹配就會(huì)停止遍歷。prefix 返回滿足條件的元素集合,drop 返回停止遍歷之后那些元素集合。
- 泛型適用于嵌套類(lèi)型。
- 類(lèi)型的擴(kuò)展可以使用約束條件,比如擴(kuò)展數(shù)組時(shí),加上元素為整數(shù)的約束,這樣的擴(kuò)展就只會(huì)對(duì)元素為整數(shù)的數(shù)組有效。
Swift 4.0
- 加入 Codable 協(xié)議,更 Swifty 的編碼和解碼。提案 SE-0167 Swift Encoders
- 字符串加入三個(gè)雙引號(hào)的支持,讓多行字符串編寫(xiě)更加直觀。提案 SE-0168 Multi-Line String Literals
- 字符串變成集合,表示可以對(duì)字符串進(jìn)行逐字遍歷、map 和反轉(zhuǎn)等操作。
- keypaths 語(yǔ)法提升。提案見(jiàn) SE-0161 Smart KeyPaths: Better Key-Value Coding for Swift
- 集合加入 ..<10 這樣語(yǔ)法的單邊切片。提案 SE-0172 One-sided Ranges
- 字典新增 mapValues,可 map 字典的值。通過(guò) grouping 可對(duì)字典進(jìn)行分組生成新字典,鍵和值都可以。從字典中取值,如果鍵對(duì)應(yīng)無(wú)值,則使用通過(guò) default 指定的默認(rèn)值。提案 SE-0165 Dictionary & Set Enhancements
Swift 4.1
- Hashable 也不需要返回一個(gè)唯一的 hashValue 哈希值屬性。
- Equatable 和 Hashable 自動(dòng)合成的提案參見(jiàn) SE-0185 Synthesizing Equatable and Hashable conformance。
- 兩個(gè)自定類(lèi)型比較是否相等時(shí),不再需要比較每個(gè)屬性,Swift 會(huì)自動(dòng)生成 == 方法,你只需要聲明 Equatable 協(xié)議。
- 引入 KeyDecodingStrategy屬性,其中 .convertFromSnakeCase 可以將下劃線的命名轉(zhuǎn)化成駝峰的命名。
- 引入條件符合性,只有滿足一定條件才符合協(xié)議。比如擴(kuò)展數(shù)組要求當(dāng)里面元素滿足某協(xié)議數(shù)組才符合這個(gè)協(xié)議。提案見(jiàn) SE-0143 Conditional conformances。
- 引入 canImport 宏條件關(guān)鍵字,判斷是否可以使用某庫(kù),以前只能通過(guò)判斷操作系統(tǒng)平臺(tái)來(lái)判斷。提案見(jiàn) SE-0075 Adding a Build Configuration Import Test。
- 新增能夠去除為零項(xiàng)目的 compactMap()。提案 SE-0187 Introduce Sequence.compactMap(_:)
- 關(guān)聯(lián)類(lèi)型可以創(chuàng)建遞歸約束,提案見(jiàn) SE-0157 Support recursive constraints on associated types
- targetEnvironment 環(huán)境的判斷,比如模擬器。提案見(jiàn) SE-0190 Target environment platform condition 。
Swift 4.2
- 新增動(dòng)態(tài)成員查詢,@dynamicMemberLookup 新屬性,指示訪問(wèn)屬性時(shí)調(diào)用一個(gè)已實(shí)現(xiàn)的處理動(dòng)態(tài)查找的下標(biāo)方法 subscript(dynamicMemeber:),通過(guò)指定屬性字符串名返回值。提案 SE-0195 Introduce User-defined "Dynamic Member Lookup" Types
- 集合新加 removeAll(where:) 方法,過(guò)濾滿足條件所有元素。比 filter 更高效。提案 SE-0197 Adding in-place removeAll(where:) to the Standard Library
- 布爾值增加 toggle() 方法,用來(lái)切換布爾值。提案見(jiàn) SE-0199 Adding toggle to Bool
- 引入 CaseIterable 協(xié)議,可以將枚舉中所有 case 生成 allCases 數(shù)組。提案 SE-0194 Derived Collection of Enum Cases
- 引入 #warning 和 #error 兩個(gè)新的編譯器指令。#warning 會(huì)產(chǎn)生一個(gè)警告,#error 會(huì)直接讓編譯出錯(cuò)。比如必須要填寫(xiě) token 才能編譯的話可以在設(shè)置 token 的代碼前加上 #error 和說(shuō)明。提案見(jiàn) SE-0196 Compiler Diagnostic Directives
- 新增加密安全的隨機(jī) API。直接在數(shù)字類(lèi)型上調(diào)用 random() 方法生成隨機(jī)數(shù)。shuffle() 方法可以對(duì)數(shù)組進(jìn)行亂序重排。提案 SE-0202 Random Unification
- 更簡(jiǎn)單更安全的哈希協(xié)議,引入新的 Hasher 結(jié)構(gòu),通過(guò) combine() 方法為哈希值添加更多屬性,調(diào)用 finalize() 方法生成最終哈希值。提案 SE-0206 Hashable Enhancements
- 集合增加 allSatisfy() 用來(lái)判斷集合中的元素是否都滿足了一個(gè)條件。提案 SE-0207 Add an allSatisfy algorithm to Sequence
Swift 5.0
- @dynamicCallable 動(dòng)態(tài)可調(diào)用類(lèi)型。通過(guò)實(shí)現(xiàn) dynamicallyCall 方法來(lái)定義變參的處理。提案 SE-0216 Introduce user-defined dynamically "callable" types
- 新加 Result 類(lèi)型用來(lái)處理錯(cuò)誤。提案 SE-0235 Add Result to the Standard Library
- 新增原始字符串能力,在字符串前加上一個(gè)或多個(gè)#符號(hào)。里面的雙引號(hào)和轉(zhuǎn)義符號(hào)將不再起作用了,如果想讓轉(zhuǎn)義符起作用,需要在轉(zhuǎn)義符后面加上#符號(hào)。提案見(jiàn) SE-0200 Enhancing String Literals Delimiters to Support Raw Text
- 自定義字符串插值。提案 SE-0228 Fix ExpressibleByStringInterpolation
- 枚舉新增 @unknown 用來(lái)區(qū)分固定的枚舉和可能改變的枚舉的能力。用于防止未來(lái)新增枚舉屬性會(huì)進(jìn)行提醒提示完善每個(gè) case 的處理。提案 SE-0192 Handling Future Enum Cases
- compactMapValues() 對(duì)字典值進(jìn)行轉(zhuǎn)換和解包??梢越饪蛇x類(lèi)型,并去掉 nil 值。提案 SE-0218 Introduce compactMapValues to Dictionary
- 扁平化 try?。提案 SE-0230 Flatten nested optionals resulting from 'try?'
- isMultiple(of:) 方法檢查一個(gè)數(shù)字是否是另一個(gè)數(shù)字的倍數(shù)。提案見(jiàn) SE-0225 Adding isMultiple to BinaryInteger
Swift 5.1
- 有序集合的 diff,通過(guò) difference(from:) 方法,可以返回要?jiǎng)h除哪些和添加哪些項(xiàng)目能夠讓兩個(gè)集合相等。提案 SE-0240 Ordered Collection Diffing
- 屬性包裝。提案 SE-0258 Property Wrappers
- 不透明返回類(lèi)型。函數(shù)調(diào)用者決定返回什么類(lèi)型是泛型,函數(shù)自身決定返回什么類(lèi)型使用不透明返回類(lèi)型。提案 SE-0244 Opaque Result Types
- 初始化有默認(rèn)值的屬性可不設(shè)置。提案 SE-0242 Synthesize default values for the memberwise initializer
- 單行表達(dá)式函數(shù)隱式返回,返回一個(gè)單行表達(dá)式的函數(shù)可以不用 return 關(guān)鍵字。提案 SE-0255 Implicit returns from single-expression functions
- 在類(lèi)、結(jié)構(gòu)體和枚舉里使用 Self,Self 可以指代包含的類(lèi)型。提案見(jiàn) SE-0068 Expanding Swift Self to class members and value types
- 靜態(tài)下標(biāo)。提案 SE-0254 Static and class subscripts
- 枚舉里有 none 的 case 編譯器會(huì)提示換成 Optional.none。
- 引入未初始化數(shù)組。提案 SE-0245 Add an Array Initializer with Access to Uninitialized Storage
Swift 5.2
- 自定義類(lèi)型中實(shí)現(xiàn)了 callAsFunction() 的話,該類(lèi)型的值就可以直接調(diào)用。提案 SE-0253 Callable values of user-defined nominal types
- 鍵路徑表達(dá)式作為函數(shù)。提案 SE-0249 Key Path Expressions as Functions
Swift 5.3
- SPM 包管理資源,SPM 可以包含資源文件,比如多媒體或文本等。通過(guò) Bundle.module 訪問(wèn)這些資源。提案 SE-0271 Package Manager Resources
- SPM 包里資源本地化。提案 SE-0278 Package Manager Localized Resources
- SPM 可以整合二進(jìn)制包依賴。提案 SE-0272 Package Manager Binary Dependencies
- SPM 可以設(shè)置特定平臺(tái)的依賴。提案 SE-0273 Package Manager Conditional Target Dependencies
- 單個(gè) catch 塊中捕獲多個(gè) Error 的 case。提案 SE-0276 Multi-Pattern Catch Clauses
- 支持多個(gè)尾部閉包。提案見(jiàn) SE-0279 Multiple Trailing Closures
- 符合 Comparable 協(xié)議的枚舉可以進(jìn)行比較。提案 SE-0266 Synthesized Comparable conformance for enum types
- 很多地方可以不用加 self 來(lái)指代實(shí)例自己了。提案見(jiàn) SE-0269 Increase availability of implicit self in @escaping closures when reference cycles are unlikely to occur
- @main 可以方便指定程序入口點(diǎn)。提案 SE-0281 @main: Type-Based Program Entry Points
- where 子句可以用到泛型和擴(kuò)展函數(shù)中。提案 SE-0267 where clauses on contextually generic declarations
- 枚舉的 case 也可以符合協(xié)議。提案 SE-0280 Enum cases as protocol witnesses
- 完善 didSet,性能提升。提案 SE-0268 Refine didSet Semantics
- 新增 Float16 類(lèi)型,即半精度浮點(diǎn)類(lèi)型。提案 SE-0277 Float16
Swift 5.4
- SPM 支持 @main。提案見(jiàn) SE-0294 Declaring executable targets in Package Manifests
- 結(jié)果生成器(Result builders),通過(guò)傳遞序列創(chuàng)建新值,SwiftUI就是使用的結(jié)果生成器將多個(gè)視圖生成一個(gè)視圖。提案 SE-0289 Result builders
- 增強(qiáng)隱式成員語(yǔ)法,即使用了隱式的成員可以進(jìn)行鏈?zhǔn)教幚?。提案?jiàn) SE-0287 Extend implicit member syntax to cover chains of member references
- 函數(shù)開(kāi)始有了使用多個(gè)變量參數(shù)的能力。提案 SE-0284 Allow Multiple Variadic Parameters in Functions, Subscripts, and Initializers
- 嵌套函數(shù)可以重載,嵌套函數(shù)可以在聲明函數(shù)之前調(diào)用他。
- 屬性包裝支持局部變量。
Swift 5.5
- Async await,用同步寫(xiě)法來(lái)處理異步。提案 SE-0296 Async/await
- Async sequences,異步序列上的循環(huán)能力。符合 AsyncSequence 協(xié)議的序列可以通過(guò) for await 來(lái)進(jìn)行異步循環(huán)。提案見(jiàn) SE-0298 Async/Await: Sequences
- 結(jié)構(gòu)化的并發(fā),使用 Task 和 TaskGroup 執(zhí)行、取消和監(jiān)聽(tīng)當(dāng)前操作的方法。復(fù)雜的并發(fā)處理可以使用 withTaskGroup() 來(lái)創(chuàng)建一組 Task,addTask() 用來(lái)添加任務(wù),cancelAll() 可以取消任務(wù),addTask() 在取消任務(wù)后可以繼續(xù)添加任務(wù),如果使用了 addTaskUnlessCancelled() 方法就可以避免取消后會(huì)繼續(xù)添加任務(wù)這種情況。提案見(jiàn) SE-0304 Structured concurrency
- 只讀屬性支持 async 和 throws 關(guān)鍵字。提案 SE-0310 Effectful Read-only Properties
- async let,可以創(chuàng)建 await 子任務(wù)。提案 SE-0317 async let bindings
- 以前異步代碼的適配。比如 DispatchQueue.main.async,外部庫(kù)可以通過(guò) withCheckedContinuation() 函數(shù)來(lái)對(duì)以前異步代碼進(jìn)行封裝。 提案見(jiàn) SE-0300 Continuations for interfacing async tasks with synchronous code
- Actor,可以確保內(nèi)部只能被一個(gè)線程訪問(wèn),避免存儲(chǔ)屬性和方法出現(xiàn)競(jìng)爭(zhēng)條件。提案在這 SE-0306 Actors
- 全局 actors,通過(guò) actor 將全局狀態(tài)隔離出來(lái),避免數(shù)據(jù)競(jìng)爭(zhēng)。比如主線程 @MainActor 這個(gè)屬性包裝可以將屬性和方法標(biāo)記為只能在主線程上訪問(wèn)。提案 SE-0316 Global actors
- Sendable 協(xié)議和 @Sendable 屬性包裝,目的是支持安全的將數(shù)據(jù)從一個(gè)線程傳給另一個(gè)線程。Swift 的核心數(shù)據(jù)類(lèi)型比如字符、集合等已符合 Sendable 協(xié)議。提案 SE-0302 Sendable and @Sendable closures
- 局部變量可以使用 lazy。
- 屬性包裝可以用到函數(shù)和閉包參數(shù)上。提案SE-0293 Extend Property Wrappers to Function and Closure Parameters
- 泛型支持靜態(tài)成員查找。提案 SE-0299 Extending Static Member Lookup in Generic Contexts
- 新增 #if 用于后綴成員表達(dá)式。提案見(jiàn) SE-0308 #if for postfix member expressions
- CGFloat 和 Double 之間可以隱式轉(zhuǎn)換。提案 SE-0307 Allow interchangeable use of CGFloat and Double types
- Codable 支持關(guān)聯(lián)值枚舉。提案 SE-0295 Codable synthesis for enums with associated values
上面各個(gè)版本的語(yǔ)法更新的內(nèi)容和更多代碼的示例都可以在 Swift 小冊(cè)子里查看,內(nèi)容力求更全,描述力求更簡(jiǎn)潔,more big, more small。不想下載 app 也可以查看《戴銘的 Swift 小冊(cè)子4.0》這篇,內(nèi)容也同步做了更新和補(bǔ)充(內(nèi)容達(dá)十五萬(wàn)字,值得你收藏和分享)。我對(duì)小冊(cè)子內(nèi)容查看樣式視覺(jué)做了更新,排版用了赫蹏(hètí),字體是霞鶩文楷,更新了代碼高亮風(fēng)格,內(nèi)容看起來(lái)更舒服。還有 icon 也進(jìn)行替換,不用再對(duì)著枯燥的 SFSymbol 和我先前臨時(shí)從以前圖里隨便挑的那條小狗 App icon 看了。
另
小冊(cè)子現(xiàn)在可以直接下載 dmg 使用了,4.3下載地址:戴銘的小冊(cè)子4.3.dmg.zip