Menu
CoddyTech

使用 tryCatch() 捕获错误

本课属于 Coddy R 学习旅程的“逻辑与流程”单元。第 53 课,共 64 课。

tryCatch(expr, error = function(e) ...)会运行expr。如果它引发错误,就会运行错误处理函数,并将其值作为结果,然后脚本会继续运行:

safe_sqrt <- function(x) {
  tryCatch(sqrt(x), error = function(e) NA)
}
print(safe_sqrt(16))
print(safe_sqrt("a"))
print("still running")

输出:

[1] 4
[1] NA
[1] "still running"

处理函数会将错误接收为 e,而 conditionMessage(e) 会返回错误消息文本:

result <- tryCatch(
  stop("file not found"),
  error = function(e) paste("Problem:", conditionMessage(e))
)
print(result)

输出:

[1] "Problem: file not found"

只包装可能失败的调用,并在你能采取有用措施的地方捕获异常,例如提供默认值或向用户显示消息:

to_number <- function(s) {
  tryCatch({
    if (s == "") stop("empty input")
    as.integer(s)
  }, error = function(e) -1L)
}
print(to_number("42"))
print(to_number(""))

输出:

[1] 42
[1] -1

在循环中,tryCatch() 可以让一个有问题的项处理失败,同时继续处理其他项:

inputs <- list(4, "x", 9)
for (v in inputs) {
  r <- tryCatch(sqrt(v), error = function(e) "not a number")
  cat(format(v), "->", r, "\n")
}

输出:

4 -> 2 
x -> not a number 
9 -> 3 
challenge icon

挑战

简单

完成 safe_divide(a, b)。使用 tryCatch():当 b 为 0 时,在其中引发 division by zero 错误,否则计算 a / b。处理程序返回 Error: ,后面跟着错误消息。将结果四舍五入到小数点后两位,并以文本形式返回,例如 3.33,或者返回错误文本。

提供的代码会读取以逗号分隔的数字对,例如 10/3,并将每对数字的结果单独打印在一行上。

亲手试试

safe_divide <- function(a, b) {
  # 在这里写你的代码
  ""
}

# 已提供的输入输出代码:保持原样
input <- suppressWarnings(readLines(file("stdin")))
for (pair in strsplit(input[1], ",")[[1]]) {
  p <- as.numeric(strsplit(pair, "/")[[1]])
  cat(safe_divide(p[1], p[2]), "\n", sep = "")
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

逻辑与流程中的所有课

自己练习: R 在线编译器