基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

try、try? 和 try! 的区别是什么?

知识点图片

在 Swift 中,trytry?try! 都是用来调用可能会抛出错误(marked with throws)的函数的关键字。它们的主要区别在于如何处理错误以及返回值的类型

简单总结如下:

  • try:标准的错误处理。需要配合 do-catch 语句块使用,或者在抛出错误的函数中继续向上传递错误。
  • try?:将结果转换为可选值 (Optional)。如果成功返回 Optional(值),如果失败返回 nil(忽略具体错误信息)。
  • try!强制执行。断言该调用绝对不会出错。如果成功返回解包后的值,如果失败则导致程序崩溃 (Runtime Crash)

下面是详细的解释和代码示例:

1. try (标准错误处理)

这是最常用的方式。当你想要捕获并处理具体的错误信息时使用。你必须把它放在 do-catch 代码块中,或者在一个同样标记为 throws 的函数内部使用。

  • 返回值:原始类型(如果成功)。
  • 错误处理:跳转到 catch 块。
plaintext
enum FileError: Error {
    case fileNotFound
    case noPermission
}

func readFile(name: String) throws -> String {
    if name == "" { throw FileError.fileNotFound }
    return "文件内容"
}

// 使用 try
do {
    let content = try readFile(name: "data.txt")
    print("读取成功: \(content)")
} catch {
    // 这里可以获取具体的 error 信息
    print("读取失败: \(error)")
}

2. try? (转换为可选值)

当你不关心具体的错误原因,只关心“成功了没有”时使用。它会将原本的错误处理机制简化为返回 nil

  • 返回值Optional<T> (例如 String?)。
  • 错误处理:如果抛出错误,结果为 nil,程序继续执行,不会崩溃。
plaintext
// 成功的情况:result 是 Optional("文件内容")
let result = try? readFile(name: "data.txt") 

// 失败的情况:failedResult 是 nil
let failedResult = try? readFile(name: "") 

// 常用配合 guard let 使用
if let content = try? readFile(name: "data.txt") {
    print(content)
} else {
    print("读取失败,但我不在乎具体是什么错误")
}

3. try! (禁止错误传递 / 强制执行)

当你百分之百确定这个函数调用在当前情况下绝对不会失败,或者如果它失败了,你认为程序应该直接停止运行(因为发生了不可能发生的逻辑错误)时使用。它类似于强制解包 (!)。

  • 返回值:原始类型 T (非 Optional)。
  • 错误处理:如果抛出错误,程序直接崩溃 (Crash)
plaintext
// 你确定文件名正确,绝对不会出错
let content = try! readFile(name: "config.json") 
// content 类型是 String,不是 String?

// 如果你判断失误,函数真的抛出了错误:
// let crash = try! readFile(name: "") 
// 💥 Fatal error: 'try!' expression unexpectedly raised an error

总结对比表

关键字 是否需要 do-catch 返回值类型 发生错误时的行为 适用场景
try 是 (或继续 throws) T 跳转到 catch 块 需要处理具体错误,或保证流程完整性。
try? T? (Optional) 返回 nil 不关心具体错误信息,只在乎成功与否。
try! T 程序崩溃 100% 确定不会出错,通常用于加载应用必须的资源或测试代码。

最佳实践建议

  1. 首选 try + do-catch,这是最安全、最标准的做法。
  2. 如果错误处理逻辑仅仅是“如果失败就不做了”,使用 try? 可以让代码更简洁。
  3. 慎用 try!。除非是在加载 App 必须的本地资源(如打包在 Bundle 里的图片或 JSON),且你确定资源一定存在。如果在网络请求或用户输入处理中使用 try!,一旦出现异常会导致 App 闪退,用户体验极差。
00:00
00:00