乐闻世界logo
搜索文章和话题

Swift 中的错误处理机制是什么?如何使用 throws、throw、try、catch?

2月21日 14:23

Swift 中的错误处理机制是什么?如何使用 throws、throw、try、catch 处理错误?

Swift 提供了一套完整的错误处理机制,允许开发者优雅地处理运行时错误。Swift 的错误处理模型与异常处理类似,但更加类型安全和可控。

错误定义:

  • 使用 Error 协议定义错误类型
  • 可以使用枚举定义具体的错误情况
  • 可以关联错误信息
  • 示例:
    swift
    enum NetworkError: Error { case invalidURL case requestFailed(Int) case noData case decodingError } enum FileError: Error { case notFound case permissionDenied case corrupted }

抛出错误:

  • 使用 throws 关键字标记可能抛出错误的函数
  • 使用 throw 关键字抛出错误
  • 示例:
    swift
    func fetchData(from urlString: String) throws -> Data { guard let url = URL(string: urlString) else { throw NetworkError.invalidURL } let (data, response) = try URLSession.shared.data(from: url) guard let httpResponse = response as? HTTPURLResponse else { throw NetworkError.requestFailed(0) } guard httpResponse.statusCode == 200 else { throw NetworkError.requestFailed(httpResponse.statusCode) } return data }

处理错误:

  1. 使用 try-catch:

    swift
    do { let data = try fetchData(from: "https://api.example.com/data") print("Data received: \(data)") } catch NetworkError.invalidURL { print("Invalid URL") } catch NetworkError.requestFailed(let statusCode) { print("Request failed with status: \(statusCode)") } catch { print("Unexpected error: \(error)") }
  2. 使用 try?:

    • 将错误转换为可选值
    • 如果发生错误,返回 nil
    • 示例:
      swift
      let data = try? fetchData(from: "https://api.example.com/data") if let data = data { print("Data received: \(data)") } else { print("Failed to fetch data") }
  3. 使用 try!:

    • 强制解包,确定不会抛出错误时使用
    • 如果抛出错误,会触发运行时错误
    • 示例:
      swift
      let data = try! fetchData(from: "https://api.example.com/data") print("Data received: \(data)")

defer 语句:

  • 在代码块退出前执行清理操作
  • 无论是否发生错误都会执行
  • 示例:
    swift
    func processFile(at path: String) throws { let fileHandle = try FileHandle(forReadingFrom: URL(fileURLWithPath: path)) defer { fileHandle.closeFile() } let data = fileHandle.readDataToEndOfFile() return data }

rethrow:

  • 将捕获的错误重新抛出
  • 用于包装函数
  • 示例:
    swift
    func processData(_ urlString: String) throws -> Data { let data = try fetchData(from: urlString) return data }

Result 类型:

  • 使用 Result<Success, Failure> 类型处理错误
  • 更函数式的错误处理方式
  • 示例:
    swift
    func fetchDataResult(from urlString: String) -> Result<Data, Error> { guard let url = URL(string: urlString) else { return .failure(NetworkError.invalidURL) } let (data, response) = URLSession.shared.synchronousData(with: url) return .success(data) } switch fetchDataResult(from: "https://api.example.com/data") { case .success(let data): print("Data received: \(data)") case .failure(let error): print("Error: \(error)") }

最佳实践:

  1. 使用枚举定义清晰的错误类型
  2. 为错误添加关联值提供更多信息
  3. 使用 try? 处理可恢复的错误
  4. 使用 defer 确保资源正确释放
  5. 在适当的地方使用 Result 类型
标签:Swift