最近在學習 Swift,總結相關知識
1. Protocols(協議)
1.1 協議的定義和實現
- 協議(
protocol
) 是一種定義方法和屬性的藍圖,任何類、結構體或枚舉都可以遵循協議。 - 遵循協議后,需要實現協議中定義的所有內容。
示例
protocol ExampleProtocol {var simpleDescription: String { get }mutating func adjust()
}
simpleDescription
: 定義了一個只讀屬性。mutating
: 標記方法可以修改遵循協議的值類型(如結構體、枚舉)。
實現協議
-
類(
class
) 遵循協議:class SimpleClass: ExampleProtocol {var simpleDescription: String = "A very simple class."var anotherProperty: Int = 69105func adjust() {simpleDescription += " Now 100% adjusted."} }
- 方法
adjust
可以直接修改屬性,無需標記為mutating
。
- 方法
-
結構體(
struct
) 遵循協議:struct SimpleStructure: ExampleProtocol {var simpleDescription: String = "A simple structure"mutating func adjust() {simpleDescription += " (adjusted)"} }
mutating
必須添加,因為結構體是值類型,默認情況下,方法不能修改實例。
1.2 擴展協議要求
向協議 ExampleProtocol
添加新的要求:
protocol ExampleProtocol {var simpleDescription: String { get }mutating func adjust()func detailedDescription() -> String
}class SimpleClass: ExampleProtocol {var simpleDescription: String = "A very simple class."func adjust() {simpleDescription += " Now 100% adjusted."}func detailedDescription() -> String {return "This is \(simpleDescription)"}
}struct SimpleStructure: ExampleProtocol {var simpleDescription: String = "A simple structure"mutating func adjust() {simpleDescription += " (adjusted)"}func detailedDescription() -> String {return "This is \(simpleDescription)"}
}
2. Extensions(擴展)
2.1 擴展定義
擴展可以用來為現有的類、結構體、枚舉或協議添加功能,例如添加方法、計算屬性或協議一致性。
示例:擴展 Int
extension Int: ExampleProtocol {var simpleDescription: String {return "The number \(self)"}mutating func adjust() {self += 42}
}
print(7.simpleDescription) // 輸出:The number 7
實驗:擴展 Double
添加 absoluteValue
extension Double {var absoluteValue: Double {return self >= 0 ? self : -self}
}
print((-3.14).absoluteValue) // 輸出:3.14
3. Error Handling(錯誤處理)
3.1 錯誤類型
- Swift 的錯誤類型必須遵循
Error
協議,通常用enum
定義。
enum PrinterError: Error {case outOfPapercase noTonercase onFire
}
3.2 拋出和捕獲錯誤
- 使用
throw
拋出錯誤,使用throws
標記函數可能拋出錯誤。 - 使用
do-catch
捕獲錯誤。
示例
func send(job: Int, toPrinter printerName: String) throws -> String {if printerName == "Never Has Toner" {throw PrinterError.noToner}return "Job sent"
}do {let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")print(printerResponse)
} catch PrinterError.noToner {print("No toner available.")
} catch {print(error)
}
3.3 使用 try?
和 defer
try?
: 拋出錯誤時返回nil
。defer
: 無論函數是否拋出錯誤,都執行清理代碼。
示例
let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler")
let printerFailure = try? send(job: 1885, toPrinter: "Never Has Toner")func fridgeContains(_ food: String) -> Bool {defer { print("Fridge closed.") } // 確保清理return ["milk", "eggs"].contains(food)
}
4. Generics(泛型)
4.1 泛型函數
- 泛型允許編寫通用代碼,支持多種類型。
func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {var result: [Item] = []for _ in 0..<numberOfTimes {result.append(item)}return result
}
makeArray(repeating: "knock", numberOfTimes: 4)
4.2 泛型類型
- 例如,重新實現 Swift 標準庫的
Optional
類型:
enum OptionalValue<Wrapped> {case nonecase some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)
4.3 泛型約束
- 使用
where
指定類型約束。
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> Boolwhere T.Element: Equatable, T.Element == U.Element {for lhsItem in lhs {for rhsItem in rhs {if lhsItem == rhsItem {return true}}}return false
}
anyCommonElements([1, 2, 3], [3])
實驗:返回公共元素數組
func commonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Element]where T.Element: Equatable, T.Element == U.Element {var result: [T.Element] = []for lhsItem in lhs {if rhs.contains(lhsItem) {result.append(lhsItem)}}return result
}
print(commonElements([1, 2, 3], [3, 4, 5])) // 輸出:[3]
總結
Swift 提供了許多現代化特性:
- Protocols 和 Extensions: 提供靈活的功能擴展和一致性約束。
- Error Handling: 提供
throw
、do-catch
、try?
等靈活的錯誤處理機制。 - Generics: 支持編寫通用、高效、類型安全的代碼。
- 類型安全性: Swift 的類型系統可以有效防止運行時錯誤,提升代碼可靠性。