Menu
CoddyTech

用 stop() 引发错误

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

stop("message") 会引发错误:函数会立即停止,后面的内容都不会运行,并且 R 会打印这条消息。当函数收到无法处理的输入时,可以使用它:

check_qty <- function(q) {
  if (q <= 0) stop("quantity must be positive")
  q
}
print(check_qty(3))
print(check_qty(-1))
print("never printed")

输出:

[1] 3
Error in check_qty(-1) : quantity must be positive
Calls: print -> check_qty
Execution halted

错误文本会指出调用失败的位置,Execution halted 表示整个脚本已停止:最后一个 print() 从未运行。错误会写入错误流,而不是正常输出,因此在 Coddy 中,只要打印出任何错误或警告,测试就会失败。

stopifnot() 会同时检查多个条件,并在第一个值为 FALSE 的条件处引发错误。命名条件会使用它的名称作为消息:

area <- function(w, h) {
  stopifnot("width must be positive" = w > 0, "height must be positive" = h > 0)
  w * h
}
print(area(2, 3))
print(area(2, -1))

输出:

[1] 6
Error in area(2, -1) : height must be positive
Calls: print -> area -> stopifnot
Execution halted

用 paste0() 或 sprintf() 根据值构建消息,让读者看出哪里出了问题:

get_item <- function(items, i) {
  if (i > length(items)) stop(sprintf("index %d is past the end (%d items)", i, length(items)))
  items[i]
}
print(get_item(c("a", "b"), 5))

输出:

Error in get_item(c("a", "b"), 5) : index 5 is past the end (2 items)
Calls: print -> get_item
Execution halted

在函数开始处、执行任何操作之前引发错误。提前停止的检查能让函数的其余部分保持简单,因为此时可以假设输入有效:

withdraw <- function(balance, amount) {
  if (amount <= 0) stop("amount must be positive")
  if (amount > balance) stop("insufficient funds")
  balance - amount
}
challenge icon

挑战

简单

完成 make_order(item, qty, stock)。使用 stop() 引发错误:

  • 当 qty 小于 1 时,提示 quantity must be at least 1
  • 当 qty 大于 stock 时,提示 only <stock> left,例如 only 3 left

否则,返回 ordered <qty> x <item>。

提供的代码会读取商品、数量和库存,调用你的函数,并打印函数的结果或 Error: 后接错误消息,因此测试不会显示 R 自己的错误文本。

亲手试试

make_order <- function(item, qty, stock) {
  # 在这里编写你的代码
  ""
}

# 提供的输入和输出代码:保持原样
input <- suppressWarnings(readLines(file("stdin")))
result <- tryCatch(make_order(input[1], as.numeric(input[2]), as.numeric(input[3])),
                   error = function(e) paste("Error:", conditionMessage(e)))
cat(result, sep = "\n")
quiz icon自我测试

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

逻辑与流程中的所有课

自己练习: R 在线编译器