Swift Protocols(协议)、Extensions(扩展)、Error Handling(错误处理)、Generics(泛型)

最近在学习 Swift,总结相关知识


1. Protocols(协议)

1.1 协议的定义和实现

  • 协议(protocol) 是一种定义方法和属性的蓝图,任何类、结构体或枚举都可以遵循协议。
  • 遵循协议后,需要实现协议中定义的所有内容。
示例
swift 复制代码
protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}
  • simpleDescription: 定义了一个只读属性。
  • mutating: 标记方法可以修改遵循协议的值类型(如结构体、枚举)。
实现协议
  • 类(class) 遵循协议:

    swift 复制代码
    class SimpleClass: ExampleProtocol {
        var simpleDescription: String = "A very simple class."
        var anotherProperty: Int = 69105
        func adjust() {
            simpleDescription += " Now 100% adjusted."
        }
    }
    • 方法 adjust 可以直接修改属性,无需标记为 mutating。
  • 结构体(struct) 遵循协议:

    swift 复制代码
    struct SimpleStructure: ExampleProtocol {
        var simpleDescription: String = "A simple structure"
        mutating func adjust() {
            simpleDescription += " (adjusted)"
        }
    }
    • mutating 必须添加,因为结构体是值类型,默认情况下,方法不能修改实例。

1.2 扩展协议要求

向协议 ExampleProtocol 添加新的要求:

swift 复制代码
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
swift 复制代码
extension Int: ExampleProtocol {
    var simpleDescription: String {
        return "The number \(self)"
    }
    mutating func adjust() {
        self += 42
    }
}
print(7.simpleDescription) // 输出:The number 7
实验:扩展 Double 添加 absoluteValue
swift 复制代码
extension Double {
    var absoluteValue: Double {
        return self >= 0 ? self : -self
    }
}
print((-3.14).absoluteValue) // 输出:3.14

3. Error Handling(错误处理)

3.1 错误类型

  • Swift 的错误类型必须遵循 Error 协议,通常用 enum 定义。
swift 复制代码
enum PrinterError: Error {
    case outOfPaper
    case noToner
    case onFire
}

3.2 抛出和捕获错误

  • 使用 throw 抛出错误,使用 throws 标记函数可能抛出错误。
  • 使用 do-catch 捕获错误。
示例
swift 复制代码
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: 无论函数是否抛出错误,都执行清理代码。
示例
swift 复制代码
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 泛型函数

  • 泛型允许编写通用代码,支持多种类型。
swift 复制代码
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 类型:
swift 复制代码
enum OptionalValue<Wrapped> {
    case none
    case some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)

4.3 泛型约束

  • 使用 where 指定类型约束。
swift 复制代码
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> Bool
    where 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])
实验:返回公共元素数组
swift 复制代码
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 提供了许多现代化特性:

  1. Protocols 和 Extensions: 提供灵活的功能扩展和一致性约束。
  2. Error Handling: 提供 throw、do-catch、try? 等灵活的错误处理机制。
  3. Generics: 支持编写通用、高效、类型安全的代码。
  4. 类型安全性: Swift 的类型系统可以有效防止运行时错误,提升代码可靠性。
相关推荐
szp20056 小时前
中文字幕烧进视频后整片空白:CoreText 低报行高,导出照样成功
ios·swift
2501_9151063214 小时前
iOS 单元测试怎么跑?用 KXApp 在 VS Code 里跑 XCTest 和 Swift Testing
ide·vscode·ios·单元测试·个人开发·swift·敏捷流程
东坡肘子15 小时前
当应用不再属于特定操作系统 -- 肘子的 Swift 周报 #159
人工智能·swiftui·swift
2501_915106324 天前
Windows 用 KXBuild 开发 iOS 项目,CocoaPods、SPM 怎么处理?
windows·vscode·ios·个人开发·swift·敏捷流程·cocoapods
2501_916008894 天前
Windows 上写第一个 SwiftUI App,KXBuild 空工程起步,跑到 iPhone 真机
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
songgeb5 天前
iOS App支持设置RTL语言的实践
ios·swift·ui kit
2501_915106327 天前
KXApp 的 VS Code 真机调试:按下 Cmd+R 之后发生了什么
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
2601_955518187 天前
36. 跨语言:C/C++与Swift&Objective-C混合编程(一)
objective-c·swift·c/c++·混合编程·跨语言
东坡肘子8 天前
谁是 AI-relay App 的真正威胁 -- 肘子的 Swift 周报 #158
人工智能·swiftui·swift
叫Guava不是瓜娃8 天前
我用 Swift 写了个本地语音输入:按住说话,松开就是整理好的文字(开源)
swift