# Introduction ## 講師介紹及課程目標 - 講師 Vandad 是一位來自瑞典的資深全端開發者,擁有豐富的 iOS 開發經驗,並製作了多個受歡迎的課程。 - 課程旨在教授 Swift 程式語言的基礎知識,不涉及特定平台(如 macOS 或 iOS)或後端開發。 - 內容涵蓋變數、常量、結構、列舉、類等基本概念,並探討 Swift 的現代特性,如 async 和 await。 ## 目標學生及先備知識 - 課程適合已熟悉其他程式語言的學生,不論是 Python、TypeScript、JavaScript 還是 Rust 等。 - 學生應該熟悉程式語言的基本概念,例如函數和變數,但不需要非常精通。 - 課程並不適合完全沒有程式語言基礎的新手,建議他們先學習其他程式語言的基礎知識。 ## 課程結構及學習方式 - 課程提供了完整的播放清單,學生可以在 YouTube 上找到。 - 內容主要以 Playground 為學習環境,Playground 具有即時運行程式碼並查看結果的功能,類似於 Flutter 中的熱重載功能。 - 對於使用 Macintosh 和 Xcode 的學生,能夠立即查看 Playgroud 中程式碼的執行結果;而對於使用 Linux 和 Visual Studio Code 的學生,需要手動運行程式碼,但不會有太大差異。 # Variables ## 理解 let 和 var 的差異 - 在 Swift 中,使用 `let` 和 `var` 關鍵字來創建變數。 - `let` 創建的變數是不可變的(immutable),而 `var` 創建的變數是可變的(mutable)。 - 即使 `let` 和 `var` 的差異在於變數是否可以重新賦值,但兩者在其他方面(如結構和類型)也有微小的差異。 ## 使用 let 和 var 創建變數 - 使用 `let` 關鍵字創建的變數是不可變的,不能重新賦值。 - 使用 `var` 關鍵字創建的變數是可變的,可以重新賦值。 - 變數的重新賦值和內部修改在 Swift 中是兩個不同的概念。 ## 使用 let 和 var 的注意事項 - 當變數指向值類型(如結構)時,`let` 防止了內部的可變性,而 `var` 允許內部的可變性。 - 當變數指向引用類型(如類)時,`let` 防止了變數的重新賦值,但允許內部的可變性。 # Operators ## 概述與基本操作 - Operators(運算子)是 Swift 中的特殊功能,用於執行各種操作。 - 在 Swift 中,運算子分為三種類型:unary prefix(一元前置)、unary postfix(一元後置)和binary infix(二元中置)。 - Binary infix 運算子是最常見的類型,它們作用於兩個值之間並位於它們之間。 - 運算子可以用於數值計算、比較以及其他操作,使得程式碼更加簡潔和易於閱讀。 ## Unary Prefix(一元前置): - 在一元前置操作中,運算子位於操作數之前,用於改變或處理該操作數的值。 - 例如,`!` 運算子可用於將布林值取反,例如將 `true` 變為 `false`。 ## Unary Postfix(一元後置): - 一元後置操作符位於操作數之後,用於對其進行後續處理。 - 雖然 Swift 內建了一些一元後置操作符,但一般情況下很少自行定義。 - 例如,對 Optional 類型使用 `!` 運算子可將其強制解析為非空值。 ## Binary Infix(二元中置): - 二元中置操作符是最常見的類型,用於操作兩個值並位於它們之間。 - 例如,`+` 運算子用於數值相加,`>` 和 `<` 運算子用於比較兩個值的大小。 ## Ternary Operator(三元運算子): - 三元運算子是一個簡潔但易於誤用的功能,用於根據條件選擇不同的值。 - 它的格式是 `condition ? value_if_true : value_if_false`,根據條件的真偽選擇返回不同的值。 ## 代碼格式化和可讀性: - 在編寫代碼時,應該考慮代碼的可讀性,適當的縮進和格式化可以使代碼更易於理解。 - Swift 目前沒有內置的代碼格式化工具,因此需要手動進行格式化以確保代碼的清晰易讀性。 # If and else ## 簡介 - 在 Swift 中,if 和 else 條件語句用於根據條件來執行不同的程式碼塊。 ## 基本條件語句 - 使用 `if` 關鍵字來開始條件語句,並根據條件的真假來執行不同的程式碼。 - 可以選擇性地添加 `else` 分支,以處理不符合條件的情況。 ## 多重分支 - 可以使用 `else if` 在原始條件的不符合情況下添加額外的條件分支。 - Swift 會逐一檢查每個條件,並執行第一個符合條件的程式碼塊。 ## 邏輯運算子的使用 - 可以使用邏輯運算子(例如 `&&` 和 `||`)來結合多個條件。 - 需要小心使用運算子,以確保預期的邏輯運算結果。 # Functions ## 基本語法 - 使用 `func` 關鍵字來定義函數。 - 函數名稱使用駝峰命名法,第一個單字小寫,後面的單字首字母大寫。 - 函數可以接受參數並指定參數的型別,在括號內列出,若無參數則括號為空。 - 函數可以有回傳值,回傳值型別在箭頭 `->` 後指定,若無回傳值則使用 `Void` 或省略箭頭。 - 函數內部由大括號 `{}` 括住執行的程式碼區塊。 ## 函數呼叫 - 函數呼叫時,使用函數名稱後跟著括號,若有參數則填入括號內。 - 若函數有回傳值且要使用,可將呼叫結果指派給一個變數或常數。 ## 函數參數 - 可以為函數參數指定外部引數名稱和內部引數名稱。 - 外部引數名稱在呼叫函數時使用,內部引數名稱在函數內部使用。 - 可為參數設定預設值,使得在呼叫函數時若不提供該參數,則使用預設值。 - 可使用底線 `_` 來省略外部引數名稱,使得呼叫函數時不需指定該參數名稱。 ## 閉包 - 閉包是一種特殊的函數,可以在函數中嵌套定義或作為獨立的程式碼塊。 - 閉包可以捕獲並存儲其周圍上下文中的值。 - 閉包可以當作參數傳遞給其他函數,也可以當作函數的回傳值返回。 ## Discardable Result - `discardable result` 是一個函數修飾符,用於表示函數的回傳值可以被忽略,不需要強制接收。 - 使用 `discardable result` 可以避免因為未使用函數回傳值而產生的編譯警告。 未加 @discardableResult ![CleanShot 2024-03-15 at 10.48.43](https://hackmd.io/_uploads/Bk9Qw4W0a.png) 已加 @discardableResult ![CleanShot 2024-03-15 at 10.49.19](https://hackmd.io/_uploads/BJuSDNbRa.png) # Closures ## Closures 概述 - Closures 是一種特殊的函數,可在其他函數中內聯使用,也可作為參數傳遞給其他函數。 - 在 Swift 中,Closures 可以像其他數據類型一樣被賦值給變量,並且可以傳遞到其他函數中。 - Closures 在 Swift 中是相當常見的,並且通常用於實現回調、排序和其他功能。 ``` let add:(Int,Int)->Int={ (lhs:Int,rhs:Int)->Int in lhs + rhs } ``` 閉包定義: * 使用了 {} 語法來定義一個閉包,它接受兩個整數參數 lhs 和 rhs,並返回一個整數結果。 * 閉包內部使用 in 關鍵字來分隔參數和主體。 * 計算 lhs 和 rhs 的總和並返回結果。 ## 創建 Closures - 使用 `{}` 大括號來定義 Closures,與函數類似,但無需使用 `func` 關鍵字。 - 可以通過將 Closures 賦值給變量或直接傳遞給其他函數來使用它們。 ## 傳遞 Closures - Closures 可以作為參數傳遞給其他函數,這使得在函數調用時可以動態地指定行為。 - 通常,Closures 用於實現回調功能,以便在某些事件發生時執行特定的操作。 ``` func customAdd( _ lhs:Int, _ rhs:Int, using function:(Int,Int)->Int )->Int{ function(lhs,rhs) } customAdd(28, 30, using: { (lhs:Int,rhs:Int)->Int in lhs + rhs }) customAdd(18, 20){ (lhr,rhs) in lhr + rhs } customAdd(8, 10) {$0 + $1} ``` ## 用途示例:排序函數 - Closures 在排序函數中特別有用,可以定義自定義的排序標準。 - 例如,可以使用 Closures 定義一個函數來比較兩個整數,從而自定義排序的順序。 ## 尾隨閉包語法 - 尾隨閉包語法使得在函數調用時更加簡潔,尤其是當最後一個參數是一個 Closures 時。 - 可以省略參數標籤,並將 Closures 直接放在函數調用的大括號內。 # Structures ## Structures 概述 - Structures 是 Swift 中用來組織資料的一種方式。 - Structures 是值類型,意味著當將一個結構的實例賦值給另一個變數時,結構內部的資料會被複製。 ## 定義結構 - 使用 `struct` 關鍵字來定義結構。 - 可以在結構內部定義屬性(properties),使用 `let` 或 `var` 關鍵字。 - 透過結構名稱的實例化,可以創建結構的實例。 ## 存取結構屬性 - 使用點運算符(`.`)來訪問結構的屬性。 - 可以直接使用點運算符訪問結構的屬性,或者將結果賦值給其他變數進行後續處理。 ## 自定義初始化器 - 結構可以有自動生成的初始化器,也可以自定義初始化器。 - 自定義初始化器讓您可以為結構提供更多的初始化邏輯,並在創建實例時設置屬性。 ## 計算屬性 - 結構可以擁有計算屬性,這些屬性的值是通過計算而來,而不是存儲在內存中。 - 計算屬性使用 `var` 關鍵字定義,並提供一個 getter 函數來計算屬性的值。 ## Mutating 函數 - 使用 `mutating` 關鍵字定義的函數允許修改結構的內部資料。 - 這是因為結構是值類型,預設情況下不允許在方法中修改其內部狀態,但 `mutating` 關鍵字允許這樣的操作。 ## 複製值 - 當將一個結構的實例賦值給另一個變數時,結構的內容會被複製到新的實例中。 - 可以通過自定義的複製函數來定制結構的複製過程,以執行自定義的複製邏輯。 # Enumerations ## Enumerations 概念介紹 - Enumerations(列舉)是 Swift 中用來分類相似值的一種概念,以命名的方式將相似的資料彙整在一起。 - 列舉讓開發者能夠以清晰明確的方式定義一組相關的值,而不需要依賴數字或字串等抽象的表示方式。 ## 列舉的使用場景 - 以動物類型為例,如果使用結構體或類別來表示動物,需要使用字串等方式來區分不同的動物類型,而這樣的表示方法可能不夠清晰或易於維護。 - 列舉提供了一種更好的方式來組織相似的值,使得程式碼更加具有表達性和可讀性。 ## Swift 列舉的基本語法 - 使用 `enum` 關鍵字來定義列舉,後面跟著列舉的名稱。 - 使用 `case` 關鍵字來定義列舉的不同情況(case),每個 case 代表了列舉中的一個可能值。 - 列舉中的 case 可以單獨列舉,也可以省略 `case` 關鍵字直接列出。 ## 列舉值的使用 - 使用點語法(dot syntax)來訪問列舉的各個情況,例如 `Animals.cat`。 - 可以將列舉值賦值給變數或常數,以便進行後續的操作或比較。 ## 列舉與條件判斷 - 使用 `if` 、`else if` 和 `else` 來進行列舉值的比較,但這種方式可能較為冗長且不易維護。 - 推薦使用 `switch` 來進行列舉值的比較,這樣可以確保所有情況都得到處理,並且可以更清晰地表達程式邏輯。 # Advanced Enumerations ## 概述與介紹 - 高級列舉的概念和特性,例如與關聯值相關的枚舉。 - 在Swift中,枚舉具有關聯值,可以在創建實例時動態添加值。 - 比較Swift的枚舉與Dart中的不同,特別是在關聯值方面的不同。 ## 枚舉與關聯值 - 使用關聯值可以將額外的信息與枚舉案例關聯起來,這些信息可以動態添加。 - 以示例展示了如何創建一個枚舉,其中不同的案例有不同的關聯值,例如URL、文件路徑、歌曲名稱等。 - 使用關聯值可以使枚舉更具彈性和通用性,而不是僅僅表示一組固定的值。 ## 自定義比較與相等性 - 當枚舉具有關聯值時,Swift無法自動推斷相等性,因此需要自定義比較運算符。 - 使用`switch`語句進行枚舉案例的比較和操作,並自行定義相等性比較邏輯。 - 可以根據需要定義不同層面的相等性,例如僅比較歌曲名稱而忽略藝術家等。 ## 無序關聯值的處理方式 - 介紹了不同的方法來處理具有關聯值的枚舉案例。 - 使用`if case let`語句可以方便地提取具有特定類型的關聯值。 - 展示了如何使用底線忽略不需要的關聯值,使代碼更簡潔。 ## 枚舉案例的操作與轉換 - 展示了如何對枚舉案例進行操作,例如創建新的關聯值或將其轉換為其他類型。 - 使用`mutating`關鍵字定義可變方法,可以修改枚舉的狀態或屬性。 - 演示了如何使用切換語句和計算屬性來操作枚舉案例。 ## 枚舉案例的原始值 - 簡介了使用原始值的枚舉,可以將固定值與枚舉案例關聯起來。 - 使用`rawValue`屬性可以獲取枚舉案例的原始值,並根據需要進行轉換或比較。 ## 遞歸枚舉 - 簡單介紹了遞歸枚舉的概念,即枚舉案例引用自身。 - 使用`indirect`關鍵字來定義遞歸枚舉,使其能夠引用自身並定義相應的操作。 - 雖然遞歸枚舉不常見,但在某些情況下可以解決特定的問題或提供更清晰的代碼結構。 # Classes ## Classes 基本概念 - Classes 是 Swift 中的一種存儲空間,與 structures 和 enumerations 不同,它是 reference types,而不是 value types。 - Classes 允許 mutability(可變性),且不需要使用 `mutating` 關鍵字。 - Class instances 通常使用 `let` 關鍵字創建,但可以內部進行更改。 ## Initializers(初始化器) - Classes 需要手動定義初始化器(initializers)。 - Designated initializers(指定初始化器)負責確保所有屬性值都被設置。 - Convenience initializers(便利初始化器)可簡化初始化過程,但最終將初始化工作委派給指定初始化器。 ## Inheritance(繼承) - Classes 支持繼承,允許創建超類和子類的關係。 - 子類可以繼承超類的屬性和方法,並且可以添加自己的功能。 ## Private Setters(私有設置器) - 屬性可以使用 `private set` 關鍵字設置為私有,使其只能在內部設置,而不能從外部設置。 - 這提供了更好的封裝和控制屬性的變化。 ## Deinitializers(析構器) - Deinitializers(析構器)在類實例被從內存中釋放時自動調用。 - 可用於執行清理操作,如釋放資源或取消註冊通知。 ## Reference Types(引用類型) - Classes 是 reference types,意味著它們在記憶體中被引用,而不是被複製。 - 傳遞 class 實例時,傳遞的是引用,而不是值的副本。這意味著對實例的更改將在所有引用之間共享。 ## 注意事項 - 需要小心將 class 實例傳遞給函數,因為它們是 reference types,可能會導致意外的行為。 - 確保適當地使用初始化器,以確保類的內部狀態正確設置。 - 使用 private set 和其他封裝技術來保護類的內部狀態和不變性。 # Protocols ## 理解協議 (Protocols) - 協議類似於其他語言中的介面(interface),定義了一組對象必須遵從的規則。 - 與類不同,協議僅定義了方法的標頭,而不包含實現。 ## 創建和實現協議 - 使用 `protocol` 關鍵字定義協議,可以包含方法和屬性的標頭。 - 類和結構可以通過遵從協議來實現其要求。 - 通過 `extension` 可以為協議中的方法提供默認實現。 ## 協議作為藍圖(Protocols as Blueprints) * 協議可以作為對象的藍圖,它定義了對象必須具有的屬性和方法。 * 通過協議的擴展,可以向遵循該協議的對象添加新的功能或方法,從而提高了代碼的可擴展性和重用性。 ## 使用 is 和 as 檢查與轉換(Using is and as for Checking and Casting) - 可以使用 `is` 關鍵字檢查對象是否符合特定協議。 - 使用 `as` 關鍵字可以將對象轉換為符合特定協議的類型。 - `as?` 關鍵字用於可選轉換,如果對象不符合協議,則返回 `nil`。 ## 協議與結構與類 - 結構是值類型,將實例傳遞給協議方法時會進行複製,不會影響原始實例。 - 類是引用類型,將實例傳遞給協議方法時,對原始實例的更改會反映在整個應用程序中。 - 結構是值類型(value types),而類是引用類型(reference types)。 * 當結構實現協議並調用協議中的 mutating 方法時,它只會在該方法的副本中進行更改,而不影響原始結構。 * 而當類實現協議時,調用 mutating 方法會直接影響到原始類的實例。 ## 注意事項 - 在使用協議時,要注意值類型和引用類型之間的差異,以免造成不必要的副作用。 - 使用協議可以實現對象間的鬆散耦合,增加代碼的靈活性和可重用性。 # Extensions ## 擴展的基本概念 - 擴展是一種能夠給現有類型添加功能的功能。 - 可以為現有的類型添加方法、計算屬性、初始化器等。 ## 在類型上添加方法 - 使用擴展可以為現有類型添加新的方法,無需修改原始類型的定義。 - 可以在擴展中定義新的方法,使其能夠在原始類型的實例上被調用。 ## 在類型上添加初始化器 - 擴展還允許在現有類型上添加初始化器,這使得可以通過不同的方式來初始化現有類型的實例。 - 使用擴展添加初始化器時,可以保留原始類型的現有初始化器。 ## 擴展現有類型以符合協議 - 可以通過擴展來使現有的類型符合特定的協議,從而為其提供協議所要求的功能。 - 這使得類型可以滿足協議的要求,並且可以在協議所定義的上下文中使用。 ## 擴展協議 - 除了在類型上進行擴展外,還可以對協議進行擴展。 - 通過擴展協議,可以向協議添加新的方法或計算屬性,從而擴展所有符合該協議的類型。 ## 為類型添加方便的初始化器 - 在擴展中定義初始化器時,可以通過擴展來為現有類型添加方便的初始化器。 - 這些初始化器可以使得在創建類型的實例時更加便捷,而不需要手動編寫重複的初始化器。 ## 延伸擴展的用途 - 擴展是一種強大的工具,可以幫助使代碼更加模組化和易於理解。 - 使用擴展可以將相關的功能組織在一起,並將其添加到相關的類型或協議中。 ## 總結 - 擴展是一種強大的語言功能,可以為現有的類型添加新的功能,從而使代碼更加模組化和易於理解。 - 通過擴展,可以在不修改原始類型定義的情況下添加新的方法、計算屬性、初始化器等,從而實現代碼的重用和組織。 # Generics ## 理解泛型 - 泛型用於避免重複編寫相同功能的程式碼。 - 利用泛型,可以輕鬆地處理多種類型的資料,並使程式碼更具彈性和重複使用性。 ## 泛型函數示例 - 示範了一個可以處理不同數值型別的函數。 - 泛型函數讓我們能夠編寫一次函數,並在不同型別間進行重複使用。 ## Associated Types in Protocols - 介紹了泛型協議中的關聯型別。 - 通過關聯型別,使得協議能夠應對不同的具體型別,並提高了協議的彈性和通用性。 ## 泛型協議的擴展 - 展示了如何對泛型協議進行擴展。 - 可以對擴展進行條件限制,使得僅特定型別符合擴展的條件。 ## 泛型類型的擴展 - 示範了如何對泛型類型進行擴展,以及如何添加新的功能。 - 透過擴展,可以對現有的泛型類型進行功能擴展,增加其使用靈活性和便利性。 ## 泛型在數組中的應用 - 展示了如何對泛型數組進行擴展,以實現特定功能,如計算平均值。 - 通過對泛型數組的擴展,可以在不改變原始數組型別的情況下,添加新的功能和操作。 # Optionals ## Optionals 概述 - Optionals 是 Swift 中一個重要的概念,表示值可能存在也可能不存在。 - 在 Swift 中,如果要處理可能為空的值,就需要使用 Optionals。 - 使用 Optionals 可以避免出現空指針異常(null pointer exception)等問題。 ## 使用 Optionals - 定義 Optionals 的方式是在型別後面加上問號(?),例如 `var age: Int?`。 - 使用 `if let` 或 `guard let` 來對 Optionals 進行安全解包。 - 使用 `if let` 可以在特定條件下安全解包 Optionals,而 `guard let` 則通常用於函數中,以確保變數的值存在。 - Optionals 可以進行比較,例如 `if age == nil` 或 `if age != nil`。 ## Switch 構造中的 Optionals - 可以使用 `switch` 構造來對 Optionals 進行處理。 - `switch` 構造可以用來匹配 Optionals 的不同狀態,例如有值(some)或沒有值(none)。 - 使用 `switch` 構造可以清晰地處理 Optionals 的不同情況。 ## Optional Chaining - Optional Chaining 可以用來訪問 Optionals 的屬性或方法,即使 Optionals 為空也不會出錯。 - 透過 Optional Chaining,可以優雅地處理可能為空的值。 ## 使用 Optionals 進行錯誤處理 - 在函數中,可以使用 Optionals 來處理可能的錯誤情況。 - 使用 `guard let` 或 `if let` 來確保必要的值存在,並在需要時返回錯誤信息。 ## 建議 - 學習並掌握 Optionals 是 Swift 開發中的關鍵,因為它們在程式中無處不在。 - 熟悉 Optionals 可以幫助開發者更有效地處理可能為空的值,提高程式碼的安全性和可讀性。 # Error Handling ## 概述 - 錯誤處理是任何支援錯誤和異常的程式語言中最重要的概念之一。 - 目的是通知調用者或使用我們代碼的人發生了錯誤,這可能是代碼本身的錯誤或調用代碼的錯誤。 - 在 Swift 中,通常我們只討論錯誤(errors),使用 `throw` 關鍵字來拋出錯誤。 ## 函數中的錯誤處理 - 使用 `throws` 關鍵字標記函數,表明函數內部可能拋出錯誤。 - 在函數內部使用 `throw` 來拋出錯誤。 - 使用 `do` 和 `catch` 來處理可能拋出的錯誤。 - 可以使用 `try` 來呼叫可能拋出錯誤的函數,並使用 `try?` 來選擇性地處理錯誤。 ## 初始化器中的錯誤處理 - 在結構或類別的初始化器中,可以使用 `throws` 來標記初始化器,表示初始化過程可能拋出錯誤。 - 在初始化器中使用 `throw` 來拋出錯誤,並在調用初始化器時使用 `try` 來處理可能的錯誤。 ## 專注處理特定類型的錯誤 - 使用 `catch` 來捕獲特定類型的錯誤,可以通過匹配錯誤的類型進行處理。 - 也可以使用 `is` 來進行模式匹配,以處理特定類型的錯誤。 ## 警告:強制解包可能引起崩潰 - 永遠不要使用 `try!` 來強制解包可能拋出錯誤的函數,因為這可能導致應用程序崩潰,影響用戶體驗。 ## 自定義錯誤 - 可以定義自己的錯誤類型,以便更好地組織和處理代碼中的錯誤情況。 - 使用枚舉類型來定義錯誤類型,並確保該枚舉類型符合 `Error` 協議。 ## 最佳實踐 - 始終優先使用 `do` 和 `catch` 來處理可能拋出的錯誤,以確保代碼的安全性和穩定性。 - 在需要時,選擇使用 `try?` 或 `try!` 來處理錯誤,但請謹慎使用,以免影響程式的可靠性。 - 使用自定義錯誤類型來更好地組織和管理代碼中的錯誤情況,提高代碼的可讀性和可維護性。 ## 概述 - 在 Swift 中,錯誤處理是一個重要的主題,它有多種方法可以處理錯誤情況。 - 可以使用 `throws` 關鍵字來標記可能會拋出錯誤的函數,並使用 `do-catch` 區塊來捕獲和處理這些錯誤。 - 另一個選擇是使用 `try?` 或 `try!` 來處理可能拋出錯誤的函數,或者直接將錯誤傳遞給調用者。 ## 使用 `throws` 標記函數 - 使用 `throws` 關鍵字來標記函數,指示它可能拋出錯誤。 - 在函數內部,可以使用 `throw` 關鍵字來拋出錯誤。 ## 使用 `do-catch` 區塊捕獲錯誤 - 使用 `do-catch` 區塊來執行可能拋出錯誤的程式碼,並捕獲和處理這些錯誤。 - 在 `do` 區塊中執行可能拋出錯誤的程式碼,在 `catch` 區塊中處理錯誤。 - 可以捕獲不同類型的錯誤,並採取相應的處理方式。 ## 使用 `try?` 和 `try!` 簡化錯誤處理 - `try?` 讓你可以嘗試調用可能拋出錯誤的函數,並將錯誤轉換為可選值。如果錯誤發生,返回 `nil`。 - `try!` 讓你可以嘗試調用可能拋出錯誤的函數,但是如果錯誤發生,會導致程序崩潰。應該謹慎使用,因為它可能導致不可預測的行為。 ## 使用 `Result` 進行錯誤處理 - `Result` 是一個枚舉類型,用於表示一個操作的結果,可以是成功的值或錯誤。 - 可以使用 `Result` 類型來替代傳統的錯誤處理方法,讓函數返回一個包含結果或錯誤的值,讓調用者根據需要進行處理。 ## 最佳實踐和注意事項 - 使用適當的錯誤處理方法來保證程式的穩定性和可靠性。 - 根據具體情況選擇適合的錯誤處理方式,並注意避免使用可能導致程序崩潰的方法,如 `try!`。 - 清晰地定義錯誤類型,使得調用者可以清楚地理解錯誤的來源和可能的解決方法。 # Collections ## Swift 中的集合類型 - 集合類型是 Swift 中用來儲存一組值的結構,主要包含數組(Array)和字典(Dictionary)。 - 在 Swift 中,集合類型也被稱為陣列、字典或 JSON 對象,具有類似其他程式語言的功能。 ## 數組(Array)的基本操作 - 數組是由相同類型的值組成的有序集合。 - 使用 `let` 定義的數組是不可變的,而使用 `var` 定義的數組可以修改。 - 可以透過索引來存取數組中的元素,索引從 0 開始。 - 常用操作包括取得第一個元素、最後一個元素、元素個數,以及對每個元素進行映射和過濾。 ## 數組的操作方法 - `append()` 方法用於在數組末尾新增元素。 - `insert(_:at:)` 方法用於在指定索引處插入新元素。 - `map()` 方法用於對數組中的每個元素進行映射,產生一個新的數組。 - `filter()` 方法用於從數組中選擇滿足特定條件的元素,產生一個新的數組。 ## 泛型函數的應用 - `map()` 方法是一個泛型函數,可以接受任何類型的數組,並傳回一個新的數組。 - 使用泛型函數可以靈活地轉換數組中的元素,例如將數字乘以 2 或轉換為字串。 ## Optional 值在陣列中的應用 - 陣列可以包含可選型的元素,即允許儲存 nil 值。 - 使用 `compactMap()` 方法可以過濾掉 nil 值,並傳回一個不包含 nil 的新數組。 ## 數組中重複元素和異質元素的處理 - 數組可以包含重複元素和異質元素。 - 使用 `compactMap()` 方法可以過濾掉 nil 值,並傳回一個不包含 nil 的新數組。 - 使用 `as Any` 或指定數組類型為 `Array<Any>` 可以處理包含異質元素的數組。 ## 總結 Swift 中的集合類型提供了豐富的操作方法,包括對數組中的元素進行映射、過濾、插入和移除等操作。 泛型函數的應用使得這些操作更加靈活和通用。 此外,可以在數組中包含可選型的元素,並通過合適的方法來處理 nil 值。 ## 介紹集合 (Sets) - 集合是一個特殊的集合,其中僅包含唯一的值。 - 集合的唯一性是基於哈希值和相等性計算的。 - 在創建集合時,它會自動去除重複的值。 - 集合中的順序不受保證,值會按照集合的規則排序。 ## 操作集合 - 可以在集合中包含 nil 值。 - 使用 `compactMap` 可以過濾掉集合中的 nil 值。 - 可以創建包含不同類型值的異構集合,需要使用 `AnyHashable` 類型。 - 使用 `as` 關鍵字可以從集合中抽取特定類型的值。 ## 自定義集合元素 - Swift 使用 `Hashable` 協議來確定集合中的元素唯一性。 - 如果自定義的類型需要放入集合中,需要實現 `Hashable` 協議。 - 除了計算哈希值外,還需實現相等性判斷。 - 可以通過實現 `hash` 和 `==` 方法來自定義哈希值和相等性判斷。 ## 操作字典 - 字典是由鍵值對組成的集合,可以使用中括號來定義。 - 使用鍵來檢索字典中的值。 - 使用 `keys` 和 `values` 可以獲取字典的鍵和值。 - 使用 `for...in` 迴圈可以遍歷字典的鍵值對。 - 可以使用 `where` 子句來篩選字典中的鍵值對。 ## Equality and Hashing - 相等性和哈希是 Swift 中重要的概念,尤其是對於集合操作。 - 了解相等性和哈希如何工作是理解 Swift 中集合行為的關鍵。 - 自定義類型時,需要注意實現相等性和哈希計算的方式,以確保正確的集合行為。 ## 總結 - 集合、數組和字典是 Swift 中常用的集合類型,熟練掌握它們的操作是開發 Swift 應用的基礎。 - 了解相等性和哈希概念可以幫助開發者更好地使用集合類型。 - 積極練習並實踐集合操作,是掌握 Swift 語言的重要一步。 # Equality and Hashing ## 概述 - 在 Swift 中,Equality 和 Hashing 是很重要的概念,用於比較和區分不同的物件。 - Swift 提供了 Equatable 和 Hashable 兩個協議,用於實現相應的功能。 - 這些功能可以直接使用,也可以進行自定義實現。 ## Equatable 協議 - Equatable 協議用於確定兩個物件是否相等。 - 默認情況下,Swift 會檢查結構和枚舉的所有屬性是否是可比較的。 - 可以自定義 Equatable 的實現,根據特定的比較條件來判斷物件是否相等。 ## Hashable 協議 - Hashable 協議用於確定物件的哈希值,這有助於在集合中快速查找物件。 - 默認情況下,Swift 會自動生成哈希值,基於物件的屬性。 - 可以自定義 Hashable 的實現,以更精確地控制哈希算法。 ## 自定義 Equality 和 Hashing - 可以通過實現 Equatable 和 Hashable 協議來自定義物件的比較和哈希值計算。 - 自定義的 Equatable 和 Hashable 實現可以根據特定的應用場景和比較需求來調整。 - 注意,在某些情況下,Swift 可能已經提供了合適的默認實現,因此需要謹慎選擇是否進行自定義實現。 ## 總結 - Equality 和 Hashing 是 Swift 中重要的概念,用於比較和區分物件。 - Equatable 和 Hashable 協議提供了相應的功能,可以根據需求進行自定義實現。 - 在進行自定義實現時,需要注意選擇適合的比較條件和哈希算法,以確保功能的正確性和效率性。 # Custom Operators ## 自訂運算子 - 運算子概念:在 Swift 中,除了內建的運算子外,還可以自訂運算子,讓程式碼更加靈活。 - 類型:可以自訂二元中置、一元前置、以及一元後置運算子。 ## 自訂二元中置運算子 - 二元中置運算子概念:用於兩個相同或不同類型的值之間的運算。 - 實作方式:定義一個函式來實現運算,並使用 `infix` 關鍵字標註運算子。 - 範例:定義將兩個 `Optional<String>` 相加的運算子,以及將兩個 `String` 相加的運算子。 ## 自訂一元前置運算子 - 一元前置運算子概念:對一個值進行操作,並將結果返回。 - 實作方式:定義一個函式來實現運算,並使用 `prefix` 關鍵字標註運算子。 - 範例:定義將字串轉換為大寫的運算子。 ## 自訂一元後置運算子 - 一元後置運算子概念:對一個值進行操作,並將結果返回。 - 實作方式:定義一個函式來實現運算,並使用 `postfix` 關鍵字標註運算子。 - 範例:定義將字串後面添加星號的運算子。 ## 自訂不同類型的二元中置運算子 - 概念:自訂運算子也可以在不同類型之間進行操作。 - 實作方式:定義一個函式來實現運算,並使用對應的參數類型。 - 範例:定義將 `Family` 和 `Person` 或 `Array<Person>` 進行結合的運算子。 # Asynchronous Programming ## 非同步程式設計基礎 - 概念:在 Swift 中,非同步程式碼是指可以延遲返回結果的函式,通常用於處理需要時間的任務,例如網路請求或者資料庫操作。 - 實作方式:使用 `async` 和 `await` 關鍵字來標註非同步函式和等待非同步操作的結果。 ## 創建非同步函式 - 定義方式:使用 `async` 關鍵字標註函式,並在需要延遲的地方使用 `await` 關鍵字。 - 範例:定義一個延遲一秒後返回結果的非同步函式 `calculateFullName`,用於計算名字的全稱。 ## 使用非同步函式 - 調用方式:在需要等待非同步操作的地方使用 `await` 關鍵字,等待函式返回結果。 - 範例:在 playground 中呼叫 `calculateFullName` 函式並使用 `await` 等待其返回結果。 ## async let 關鍵字 - 概念:`async let` 用於在非同步函式中定義並等待多個非同步操作的結果。 - 使用方式:在非同步函式或非同步尾隨閉包中使用 `async let`,並在後續程式碼中等待結果。 - 注意事項:只能在符合上下文的情況下使用,如非同步函式或尾隨閉包。 ## 優化非同步程式碼 - 簡化語法:使用 `async let` 可以簡化多個非同步操作的等待,但也增加了程式碼的複雜性。 - 建議:雖然 `async let` 提供了便利,但有時可能會增加程式碼的難以理解性,需要根據情況適當使用。 ## 非同步程式設計的重要性 - 應用場景:非同步程式碼常用於處理網路請求、資料庫操作等耗時任務,提高應用的性能和效率。 - 重要性:學習並掌握非同步程式設計是現代軟體開發中不可或缺的一部分,有助於提高程式碼的效率和可靠性。 ## Swift 中的非同步特性 - 語法:Swift 的非同步特性借鑑了其他程式語言的設計,如 JavaScript、TypeScript 和 Dart,但也有一些獨特的語法和特性。 - 學習:儘管有些語法可能會增加程式碼的複雜性,但了解和學習這些特性仍然是重要的,以應對現代軟體開發中的需求。 ## 總結 - Swift 提供了豐富的非同步程式設計功能,包括 `async`、`await` 和 `async let` 等關鍵字,有助於處理各種耗時任務。 - 非同步程式設計在現代軟體開發中扮演著重要角色,學習並掌握這些技術有助於提高程式碼的效率和可靠性。 # Outro # 關鍵字 - Swift Programming Language: 一種由蘋果公司開發的程式語言,用於 iOS、macOS、watchOS 和 tvOS 應用程式的開發。 - Playground: Swift 提供的一種開發環境,可以立即運行程式碼並查看結果,用於實驗和學習 Swift 語言。 - Full Stack Developer: 擁有前端和後端開發技能的開發者,能夠處理整個應用程式的開發工作。 - Async and Await: Swift 中的現代特性,用於處理非同步操作,提供更簡潔和易於理解的程式碼。 - Workspace: Xcode 中的一個概念,用於組織和管理多個專案和文件,方便開發者進行項目管理和協作。 - Visual Studio Code: 一個由微軟開發的跨平台程式碼編輯器,支援多種程式語言,包括 Swift。 - Compiler: 編譯器,將人類可讀的程式碼轉換為電腦可執行的機器碼或字節碼的工具。 - Terminal/Console: 用於在命令行界面中執行程式碼的工具,例如在 Linux 中使用 Swift 編譯器運行程式碼。 - let: 在 Swift 中,用於創建不可變變數的關鍵字,該變數一旦賦值就不能再次修改。 - var: 在 Swift 中,用於創建可變變數的關鍵字,該變數可以被重新賦值。 - 值類型(Value Types): 在 Swift 中,指的是結構和列舉等,它們在賦值時是進行複製,每個變量都有自己的獨立內存空間。 - 引用類型(Reference Types): 在 Swift 中,指的是類(class)等,它們在賦值時是進行引用,多個變量指向同一個內存空間。 - 結構(Structures): 在 Swift 中是一種值類型,使用 `let` 創建的結構變數防止了內部的可變性。 - 類(Classes): 在 Swift 中是一種引用類型,使用 `let` 創建的類型變數防止了重新賦值,但允許內部的可變性。 - append 函數: 在 Swift 中,用於向集合(如數組或列表)的末尾添加新元素的函數。該函數將指定的元素附加到集合的末尾,修改了集合本身,並返回修改後的集合。在本文中,示例中使用了 append 函數將新元素添加到數組中。 - NSMutableArray: `NSMutableArray` 是 Objective-C 中的類型,用於創建可變的數組。在 Swift 中,它通常被視為 `NSArray` 的可變版本。在 Swift 與 Objective-C 混合編程的情況下,可以使用 `NSMutableArray` 來處理需要動態添加或刪除元素的數組操作。 - NSArray: NSArray 是 Objective-C 中的類型,用於創建不可變的數組。在 Swift 中,它對應到 Array 類型的不可變版本。NSArray 的元素是固定的,一旦創建後就不能添加、刪除或修改元素。在 Swift 與 Objective-C 混合編程的情況下,可以使用 NSArray 來處理需要靜態數組的操作。 - as!: `as!` 是 Swift 中的一個轉型運算符,用於強制轉換資料類型。在這個例子中,`as!` 被用來將 `array` 變數的類型轉換為 `NSMutableArray`,這是一種 Objective-C 中的可變數組類型。當我們確定 `array` 包含可變數據時,可以使用 `as!` 來強制轉換為 `NSMutableArray`,以便可以修改其內容。值得注意的是,使用 `as!` 操作符進行強制轉換時,如果轉換失敗,會導致運行時錯誤,因此應該確保轉換的安全性。 - Operators(運算子):用於執行各種操作的特殊功能。 - Unary Prefix(一元前置):位於操作數之前並用於改變其值的運算子類型。 - Unary Postfix(一元後置):位於操作數之後並對其進行後續處理的運算子類型。 - Binary Infix(二元中置):位於兩個操作數之間並對它們執行操作的運算子類型。 - Ternary Operator(三元運算子):根據條件選擇不同值的特殊運算子類型,格式為 `condition ? value_if_true : value_if_false`。 - Format(格式化):調整代碼的排版和結構,以提高可讀性和理解性。 - Optional(可選型):在 Swift 中,可選型表示一個值可能是空(nil)或具有某種特定類型的值。可選型通常用於處理可能為空的情況,以防止空值引起的錯誤。 - type(of:)(類型查詢函式):`type(of:)` 是一個 Swift 標準函式,用於獲取指定實例的類型。它返回該實例的類型,通常用於調試和動態類型檢查的情況下。 - if:Swift 中的關鍵字,用於指定一個條件,並根據該條件的真假來執行不同的程式碼塊。 - else:可選的關鍵字,在 `if` 條件不符合時執行相應的程式碼塊。 - else if:可選的關鍵字,用於添加額外的條件分支,並在原始條件不符合時進行進一步的條件檢查。 - 邏輯運算子:用於結合多個條件的運算子,如 `&&`(AND)和 `||`(OR),用於構建更複雜的條件邏輯。 - `func`: 用於定義函數的關鍵字。 - 駝峰命名法: 將單字連接在一起,並將每個單字的第一個字母大寫,用於命名變數、函數等識別符。 - 參數: 函數接受的輸入值,在函數定義中列出。 - 回傳值: 函數執行完畢後返回的值。 - 閉包: 一種可以被嵌套在其他函數中的函數,或者可以作為獨立的程式碼區塊存在。 - 捕獲: 閉包可以捕獲並存儲其周圍上下文中的值,這些值可以在閉包內使用,即使周圍的上下文已經不存在。 - 外部引數名稱(external argument label): 在函數呼叫時使用的參數名稱,用於標識傳遞給函數的參數。外部引數名稱可讓函數的呼叫者更清晰地理解函數的用途,並提高代碼的可讀性。 - 內部引數名稱(internal argument label): 在函數內部使用的參數名稱,用於在函數內部引用傳遞給函數的參數。內部引數名稱是函數內部的局部變數名稱,用於執行函數內的操作。 - 預設值: 可以為函數參數設定的默認值,在呼叫函數時若不提供該參數,則使用預設值。 - 底線 `_`: 在函數定義中,用於省略外部引數名稱,使得呼叫函數時不需指定該參數名稱。 - `discardable result`: 一個函數修飾符,表示函數的回傳值可以被忽略,不需要強制接收。 - with: 在函數呼叫時用於指定參數的前綴詞,用來標識傳遞給函數的特定參數。在函數定義中,with 可以用於提供清晰的函數調用語法,讓函數的呼叫者更容易理解參數的作用。 - Closures:在 Swift 中,Closures 是指無需命名和定義的功能塊,可以在需要時內聯使用或作為參數傳遞給其他函數。 - 函數引用:將函數賦值給變量或常量,以便稍後調用,這種方式稱為函數引用或函數變量。 - 尾隨閉包:當一個函數的最後一個參數是一個 Closures,且該 Closures 是傳遞給該函數的唯一參數時,可以使用尾隨閉包語法,使函數調用更加簡潔。 - 排序函數:排序函數是一種接受 Closures 參數的函數,用於對數據集進行排序,Closures 定義了排序的標準或比較方式。 - 回調函數:回調函數是一種特殊的 Closures,通常用於異步編程中,用於在某些事件發生時執行特定的操作,例如網絡請求完成時的回調。 - on: 在這個上下文中,"on" 是一個函式的參數標籤(parameter label),用於識別傳遞給函式的值。它提供了對參數的描述性語境,讓使用函式的人能夠更清楚地理解該值的意義。 - using function: "using" 作為一個參數標籤,用於識別傳遞給函式的 Closure。"function" 是一個名稱,指示 Closure 的用途,通常用於執行某種操作或計算。這種形式的參數標籤可以幫助提高代碼的可讀性,並使其更易於理解。 - 結構 (Structures): Swift 中的一種用來組織資料的類型,是值類型,使用 `struct` 關鍵字定義。 - 值類型 (Value types): 在 Swift 中,值類型是指結構、列舉和基本數據類型,它們的實例在賦值給其他變數時是被複製的。 - 屬性 (Properties): 結構內部的變數,用於存儲和描述結構的狀態或數據。 - 初始化器 (Initializers): 用於初始化結構實例的特殊方法,可以是自動生成的或自定義的。 - 計算屬性 (Computed properties): 結構中通過計算而得到的屬性值,而不是存儲在內存中。 - Mutating 函數 (Mutating functions): 用於在結構中修改內部狀態的函數,在定義時使用 `mutating` 關鍵字標記。 - 複製值 (Copying values): 當將結構的實例賦值給另一個變數時,結構內容會被複製到新的實例中,這是因為結構是值類型。 - 列舉(Enumerations):Swift 中用來將相似值分類和組織的概念,以清晰的命名方式表示相關的值。 - `enum` 關鍵字:用於定義列舉的關鍵字,後面跟著列舉的名稱和相關的情況。 - `case` 關鍵字:用於定義列舉中的不同情況(case),每個 case 代表了一個可能的值。 - 點語法(dot syntax):用於訪問列舉中的情況或成員,格式為 `EnumName.caseName`。 - `switch` 語句:用於根據列舉值的不同情況執行不同的程式碼區塊,是一種比較列舉值的常用方式。 - 處理不完整性(Exhaustiveness):在使用 `switch` 語句時,要求確保對所有列舉情況進行處理,以避免不完整的程式碼。 - 關聯值(Associated values):在Swift中,枚舉案例可以與關聯值相關聯,這些值在創建實例時動態添加,使枚舉更具彈性。 - 自定義比較(Custom equality):當枚舉具有關聯值時,需要自行定義相等性比較邏輯,以便在需要時進行正確的比較。 - 原始值(Raw values):與枚舉案例關聯的固定值,可用於簡單的映射或比較。 - 遞歸枚舉(Recursive enumerations):一種枚舉,其中某些案例引用自身,通常用於處理具有遞歸結構的問題或定義複雜的數據結構。 - **類別 (Classes)**:在 Swift 中是一種參考型別,與結構不同,它們被用來創建對象,並可以具有方法、屬性和初始化器。 - **參考型別 (Reference Types)**:類別是參考型別,這意味著當你將一個類別的實例傳遞給函數或變量時,它實際上是將對該實例的引用傳遞過去,而不是實際的值的拷貝。 - **初始化器 (Initializers)**:在類別中用於初始化新實例的特殊方法。它們可以是指定初始化器(designated initializer)或方便初始化器(convenience initializer)。指定初始化器必須為所有存儲屬性設置初始值。 - **指定初始化器 (Designated Initializer)**:在類別中負責為所有屬性設置初始值的初始化器。指定初始化器不能調用其他指定初始化器。 - **方便初始化器 (Convenience Initializer)**:在類別中為方便使用而設置的初始化器。方便初始化器通常會調用同一類別中的其他初始化器,最終會調用指定初始化器。 - **私有設置 (Private Setters)**:可以在類別中將屬性設置為私有的,這意味著它們只能在類別的內部設置,無法從外部設置。 - **繼承 (Inheritance)**:類別可以通過繼承從其他類別獲取屬性和方法。子類繼承了父類的所有成員,但也可以添加自己的新成員或重寫父類的成員。 - **析構器 (Deinitializers)**:與初始化器相對應,析構器是一個在實例被釋放時執行的特殊方法。用於在實例被回收前執行清理工作,如釋放資源。 - **相等性運算子 (Equality Operators)**:用於比較類別實例的相等性的運算子。在 Swift 中,類別的相等性判斷通常基於引用是否指向同一個實例。 - **私有成員 (Private Members)**:在類別中可以將某些成員標記為私有,這意味著它們只能在該類別的內部訪問,無法在外部訪問。 - **無法變更 (Immutable)**:類別的 let 常數實例是無法被重新賦值的,但是其內部屬性的值仍然可以被修改。 - **不可變性 (Immutability)**:與結構不同,類別的實例在創建後其內部屬性的值是可以被修改的,即使該實例是用 let 常數創建的。 - **實例方法 (Instance Methods)**:屬於類別的方法,作用於類別的實例,可以訪問和修改實例的屬性值。 - **讀寫權限 (Read-Write Access)**:指定類別屬性是否允許讀取和寫入的權限,可以根據需要將屬性設置為讀取和寫入或只讀取。 - **類型轉換 (Type Casting)**:用於檢查實例的類型或將實例視為其父類型或子類型的操作。 - **垃圾回收 (Garbage Collection)**:自動管理記憶體的機制,用於釋放不再使用的對象以節省記憶體資源。在 Swift 中,使用 ARC (Automatic Reference Counting) 來管理記憶體,並在對象不再被引用時自動釋放其記憶體。 - 協議(Protocols):在 Swift 中,協議是一種定義方法、屬性和其他功能的藍圖,可以被類別、結構或枚舉類型採納以提供所需的功能。它類似於其他語言中的介面(interface)概念,並用於定義對象的行為。 - 類別(Class):在 Swift 中,類別是一種引用類型,可以創建基於類的對象,並且支持繼承。 - 結構(Structures):結構是一種值類型,在 Swift 中用於創建包含屬性和方法的自定義數據類型,並且不支持繼承。 - 實作(Conforming):當類別、結構或枚舉採納(adopt)了協議時,它們被認為是符合(conform)該協議的,並且必須實現協議中定義的所有必要功能。 - 擴展(Extensions):通過擴展,可以向現有的類別、結構或枚舉類型添加新的功能,包括協議的實作。 - 可變方法(Mutating Methods):在結構和枚舉類型中,如果要在方法中修改自身的屬性或值,需要將該方法標記為 mutating。這使得該方法可以修改結構或枚舉類型的實例。 - 類型轉換(Type Casting):使用 is 和 as 關鍵字來檢查實例是否符合某個協議,以及將實例轉換為特定類型。如果轉換成功,則可以使用該類型的功能。 - 可選型(Optionals):在 Swift 中,可選型是一種特殊的類型,可以表示一個值是存在的(有值),或者是不存在的(nil)。這在處理可能為空的值時非常有用。 - **Extensions**: Swift 中的擴展(extensions)是一種機制,用於為現有的類型(classes)、結構(structures)、枚舉(enums)或協議(protocols)添加額外的功能或協議遵從(conformance)。 - **初始化器(Initializers)**: 擴展可以向現有的類型添加新的初始化器(initializers),這些初始化器可以提供額外的方便或選擇性的方式來初始化對象。 - **類型遵從協議(Conforming to Protocols)**: 通過擴展,可以使類型遵從(conform to)新的協議,從而為該類型添加協議所定義的方法和屬性。 - **協議擴展(Protocol Extensions)**: 可以使用擴展來擴展現有的協議,以添加新的方法或屬性。這使得所有遵從該協議的類型都能夠使用這些新功能。 - **便利初始化器(Convenience Initializers)**: 便利初始化器是指在類型的擴展中定義的初始化器,它們可以通過調用類型自身的其他初始化器來簡化對象的初始化過程,但不能改變該類型的內部狀態。 - **泛型(Generics)**: 擴展是 Swift 語言中一個強大的特性,它們允許開發者對現有的類型進行擴展,添加新功能或實現新的協議遵從。通過靈活使用擴展,開發者可以使代碼更具彈性和可擴展性。 - 泛型(Generics):一種程式設計機制,允許在定義函式、結構、列舉等時使用參數化類型,使得程式碼可以針對不同類型進行重用。 - 關聯類型(Associated Types):在 Swift 中,協定(Protocol)可以使用關聯類型定義一個或多個關聯型別,這些關聯型別在協定中未指定具體類型,而是在採用該協定的類型中定義。 - 泛型協定(Generic Protocols):具有關聯類型的協定,可以用來定義泛型函式、結構或類型,讓實際的型別在採用時指定。 - 泛型擴展(Generic Extensions):對泛型類型進行擴展,使其可以具有新的方法或屬性。在擴展中可以使用泛型條件來限制擴展僅適用於特定型別或滿足特定條件的型別。 - 降級(Downcasting):將一個較泛型的類型轉換為其較具體的子類型的過程,通常使用 as 關鍵字來執行。 - 泛型條件(Generic Constraints):限制泛型類型的條件,例如要求某個泛型類型實現特定協定或滿足某種條件,以確保在泛型代碼中使用這些類型時的安全性和正確性。 - **Optionals (選擇性類型)**: 在 Swift 中,選擇性類型表示一個值可能存在,也可能不存在。這允許我們明確處理缺少值的情況,避免出現意外的錯誤或空指針異常。 - **Unwrapping (解包)**: 將選擇性類型的值提取出來,以便進行操作或檢查。解包時需要確保值是存在的,否則可能導致運行時錯誤。 - **Optional Binding (選擇性綁定)**: 使用 `if let` 或 `guard let` 構造來將選擇性類型的值解包並賦值給一個新的非選擇性變量。這樣可以在值存在時進行操作,否則執行特定的錯誤處理邏輯。 - **Nil-Coalescing Operator (空值合併運算符)**: 使用 `??` 運算符來提供一個默認值,當選擇性值為 `nil` 時使用。這使得在選擇性值為 `nil` 時返回一個預設值成為可能。 - **Optional Chaining (選擇性鏈式調用)**: 使用 `?` 來調用選擇性類型的屬性或方法,如果該值為 `nil`,則整個鏈式調用將提前返回 `nil`,避免了因為 `nil` 值而導致的執行時錯誤。 - **Optional Enumerations (選擇性枚舉)**: Swift 中的選擇性類型實際上是一個枚舉,該枚舉有兩個可能的值:`none` 表示值不存在,`some` 表示值存在並且包含一個具體的值。這使得可以通過 `switch` 來對選擇性值進行模式匹配和處理。 - **Error Handling (錯誤處理)**: 錯誤處理是一種機制,用於處理可能發生的錯誤或異常情況,使程序能夠更優雅地處理問題並繼續執行。在 Swift 中,錯誤通常是通過拋出錯誤(`throw`)和捕獲錯誤(`try-catch`)來處理。 - Nil(空值):表示缺少值的特殊值,在 Swift 中使用 nil 來表示 Optional 的空值狀態。 - Optional Pattern Matching(Optional 模式匹配):可以使用 switch 來對 Optional 進行模式匹配,以處理其可能的兩種情況:有值和沒有值。 - **錯誤(Error)**:在 Swift 中,錯誤是指程式執行中遇到的問題或不正確的情況。當一個函式或初始化器可能遇到問題時,它可以拋出一個錯誤以通知調用方。 - **拋出(Throw)**:`throw` 關鍵字用於在函式或初始化器中拋出錯誤。它表示函式可能會發生錯誤並將錯誤傳遞給調用方。 - **錯誤處理(Error Handling)**:錯誤處理是指在程式中處理可能發生的錯誤的機制。在 Swift 中,錯誤可以通過 `do` 和 `catch` 塊來處理。 - **do-catch 塊**:`do` 和 `catch` 是一對關鍵字,用於創建一個區塊,在其中可以拋出和捕獲錯誤。`try` 關鍵字用於標記可能拋出錯誤的代碼,而 `catch` 塊用於捕獲和處理拋出的錯誤。 - **錯誤類型(Error Type)**:在 Swift 中,錯誤通常是用枚舉類型(Enum)來表示的。開發者可以定義自己的錯誤類型,並在需要時拋出這些錯誤。 - **錯誤捕獲(Error Catching)**:使用 `catch` 塊來捕獲和處理拋出的錯誤。可以根據錯誤的類型來捕獲不同的錯誤,也可以使用 `catch` 塊捕獲所有錯誤。 - **選擇性嘗試(Optional Try)**:使用 `try?` 來將可能拋出錯誤的函式調用轉換為一個可選值。如果函式調用成功,則返回一個包含返回值的可選值;如果函式拋出錯誤,則返回 `nil`。 - **強制解包嘗試(Forced Try)**:使用 `try!` 來將可能拋出錯誤的函式調用轉換為一個非可選值。如果函式調用成功,則返回值被強制解包;如果函式拋出錯誤,則導致程式崩潰。 - 錯誤處理(Error Handling):在程式開發中,處理錯誤是一個重要的議題。當程式執行遇到錯誤時,可以使用錯誤處理機制來妥善處理這些錯誤情況,以確保程式的穩定性和可靠性。 - 拋出函式(Throwing Functions):這是一種在程式執行遇到錯誤時拋出錯誤的方式。被標記為「拋出函式」的函式可以在內部使用關鍵字「throw」來拋出錯誤,並在函式調用時使用「try」關鍵字來捕獲可能的錯誤。 - 捕獲錯誤(Catching Errors):為了處理拋出的錯誤,我們可以使用「do-catch」區塊來捕獲可能的錯誤。在這個區塊中,我們可以使用多個「catch」區塊來處理不同種類的錯誤,以及一個「catch」區塊來處理未知錯誤。 - 可選的拋出(Optional Try):除了使用「try」關鍵字來拋出錯誤外,還可以使用「try?」來將可能的錯誤轉換為可選值,如果函式拋出錯誤,則結果將為「nil」,否則將返回函式的結果。 - 強制拋出(Forced Try):雖然可以使用「try?」來處理可能的錯誤,但也可以使用「try!」來強制執行函式並忽略可能的錯誤,這樣做可能導致程序崩潰,因此應該謹慎使用。 - 多個錯誤捕獲(Multiple Error Catching):在「do-catch」區塊中,可以使用多個「catch」區塊來捕獲多種不同類型的錯誤,但只有第一個匹配的「catch」區塊將被執行。 - 重新拋出(Rethrows):當一個函式內部調用了另一個可能拋出錯誤的函式時,可以使用「rethrows」關鍵字來標記這個函式,這樣做可以讓調用者知道這個函式可能會拋出錯誤。 - 結果(Results):除了拋出錯誤外,還可以使用「Result」類型來處理可能的錯誤。這種方式更具靈活性,可以明確指定可能的錯誤類型,並使用「success」和「failure」來表示函式的執行結果。 - 集合(Collections):在程式設計中指的是一組物件或數值的集合。 - 陣列(Array):一種在程式中儲存多個相同類型元素的容器,可以通過索引來訪問元素。 - 字典(Dictionary):一種鍵-值對的集合,每個值都與唯一的鍵相關聯。 - JSON(JavaScript Object Notation):一種輕量級的資料交換格式,常用於網頁開發中。 - 映射(Mapping):將集合中的元素映射為另一種形式的過程。 - 變異(Mutating):對集合進行改變或修改的操作。 - 泛型(Generic):具有彈性的程式碼設計概念,可讓類型參數化,提高程式碼的重用性。 - 篩選(Filtering):從集合中篩選出符合特定條件的元素。 - 索引(Index):在陣列中指定元素位置的整數值,通常從零開始。 - 可選值(Optional):表示可能包含或不包含值的容器類型。 - 可選鏈(Optional chaining):用於處理可能為空的鏈式屬性或方法調用的機制。 - 合併(Append):將元素添加到集合的末尾。 - 插入(Insert):將元素插入集合的指定位置。 - 遍歷(Enumerate):逐個訪問集合中的元素。 - 匹配模式(Pattern matching):用於檢查值是否符合特定模式的語言功能。 - 可選型別轉換(Optional type conversion):將包含可選值的集合轉換為不包含可選值的集合。 - **Equatable Protocol**: 一個協議,用於提供 Swift 中的相等性。任何符合 Equatable 協議的對象都必須具有一個名為 `==` 的靜態函數,該函數接受兩個相同類型的參數,並返回布林值,指示兩個對象是否相等。 - **Hashable Protocol**: 一個協議,用於提供 Swift 中的雜湊功能。任何符合 Hashable 協議的對象都必須具有一個名為 `hashValue` 的屬性,該屬性返回對象的雜湊值。 - **Hash Value (雜湊值)**: 一個整數值,用於代表對象的獨特標識。這個值通常用於儲存對象在集合中的位置,確保集合中沒有重複的對象。 - **Struct (結構)**: 一種用於定義值型別的構造體,它可以包含屬性和方法。結構可以遵循 Equatable 和 Hashable 協議,以提供自定義的相等性和雜湊功能。 - **Enum (列舉)**: 一種用於定義有限可能性的型別。列舉可以具有相關值或原始值,並且可以遵循 Equatable 和 Hashable 協議,以提供自定義的相等性和雜湊功能。 - **Set (集合)**: 一種無序、不可重複的集合型別,它存儲獨特的值。Set 使用雜湊值來確保每個值在集合中只出現一次。 - **Associated Values (相關值)**: 列舉中的值,與列舉案例相關聯。具有相關值的列舉案例可以携帶附加信息。 - **Raw Values (原始值)**: 列舉中固定的預先定義的值,它們與列舉案例一一對應。原始值必須是相同型別的常量。 - **Static Function (靜態函數)**: 屬於類別或結構本身而不是類別或結構的實例的函數。它可以直接通過類別或結構的名稱調用,而無需創建實例。 - **Operator Overloading (運算符重載)**: 在 Swift 中,可以通過實現特定協議的相應函數來自定義運算符的行為。例如,`==` 運算符可以被重載以實現相等性比較。 - **Pattern Matching (模式匹配)**: 在 Swift 中,用於檢查值是否匹配特定模式的機制。它通常與 switch 語句一起使用,但也可以在 if 陳述中使用。 - **Extension (擴展)**: 用於在不更改原始類別或結構的情況下為其添加新功能的機制。擴展可以用於實現協議、添加新屬性或方法等。 - **Type Inference (型別推斷)**: Swift 的一項功能,允許編譯器根據上下文推斷表達式中的型別,而不需要顯式地聲明它們。 - **Shorthand Syntax (簡寫語法)**: Swift 中的簡潔語法形式,用於簡化常見的編碼模式。例如,使用點語法代替完整的型別名稱,或使用簡化的 for 迴圈語法。 - `Equatable`(可相等性):一個 Swift 協議,用於定義兩個類型是否相等的條件。如果一個類型符合 Equatable 協議,則可以使用相等運算符(==)來比較兩個實例是否相等。該協議要求實現一個名為 `==` 的靜態函數,並比較兩個實例的相等性。 - `Hashable`(可哈希性):一個 Swift 協議,用於定義類型的哈希值。如果一個類型符合 Hashable 協議,則可以將其用於集合(如 Set 或 Dictionary)的鍵,並且可以使用該類型的實例計算哈希值。該協議要求實現一個名為 `hashValue` 的屬性,以及一個名為 `hash(into:)` 的方法,用於將實例的屬性組合成一個哈希值。 - 哈希值:在計算哈希表中的索引時使用的數值。它是根據對象的屬性計算得出的,具有相同屬性的對象應該具有相同的哈希值。 - 相等性:兩個對象之間的相似程度。在 Swift 中,可以使用 Equatable 協議來比較兩個對象的相等性。相等性通常是使用 `==` 運算符來確定的。 - 協議(Protocol):在 Swift 中,協議是一種定義方法、屬性和其他功能的藍圖,但不提供實際的實現。類型可以遵從(conform to)協議,並實現協議中定義的要求。 - 集合(Collection):在 Swift 中,集合是一組相關的值的容器,如陣列(Array)、集合(Set)和字典(Dictionary)。集合提供了對其中元素的快速查找和訪問的功能。 - 自定義運算子(Custom Operators):在程式設計中,指開發者自行定義的運算子,用於執行特定的操作或計算。 - 一元前置運算子(Unary Prefix Operators):一種類型的自定義運算子,僅對其右側的操作數進行操作,並在其前置。 - 一元後置運算子(Unary Postfix Operators):一種類型的自定義運算子,僅對其左側的操作數進行操作,並在其後置。 - 二元中置運算子(Binary Infix Operators):一種類型的自定義運算子,對其左右兩側的操作數進行操作,並位於其中間。 - 哈希值(Hash Value):在程式語言中,用於將數據結構轉換為唯一標識的數值,通常用於確定數據結構在集合中的位置。 - 等價性(Equality):在程式設計中,指兩個數據結構或對象具有相同的值或特性。 - Equatable協議(Equatable Protocol):在Swift語言中,一個協議,允許類型進行等價比較,需要實現相應的等價性判斷函數。 - Hashable協議(Hashable Protocol):在Swift語言中,一個協議,允許類型生成唯一的哈希值,通常用於將類型作為鍵存儲在集合中。 - 非同步(Asynchronous):在程式設計中,指不立即返回結果的操作或函數,而是可能需要一段時間才能完成並返回結果。 - 非同步函數(Asynchronous Function):一種函數,通常用於執行非同步操作,它會在完成任務後返回結果,並在等待期間不會阻塞程式的執行。 - 任務(Task):在Swift中,指一個非同步操作的執行單元,通常與非同步函數一起使用,用於管理和追蹤非同步操作的進度和結果。 - async let:Swift中的一種語法,用於在非同步上下文中聲明和等待結果,通常與非同步函數和非同步閉包一起使用,使程式碼更容易理解和編寫。 - 無限執行(Indefinite Execution):在Swift Playgrounds中的一種設置,用於確保非同步程式碼的執行不會因為程式結束而中止,通常用於確保非同步操作可以順利完成。 - 調試字串轉換協議(Custom Debug String Convertible Protocol):在Swift中,一個協議,用於定義自定義類型如何將自身轉換為調試用的字串表示形式,通常用於自定義類型的調試和日誌記錄。 # 待研究 guard none some rethrows