This https://stat.ethz.ch/pipermail/r-help//2013-February/347056.html这篇文章引用了 R 条件处理的灵感。
对于1.,我想到simpleCondition
说明如何构建自定义条件,例如。
myCondition <-
function(message, call=NULL, type=c("overflow", "underflow", "zero"))
{
type <- match.arg(type) # only allowed types past here
class <- c(type, "my", "condition")
structure(list(message = as.character(message), call = call),
class = class)
}
是一个用于创建自定义条件的构造函数
> myCondition("oops")
<overflow: oops>
> myCondition("oops", type="underflow")
<underflow: oops>
这些条件可用于tryCatch
or withCallingHandlers
xx <- tryCatch({
signalCondition(myCondition("oops", type="underflow"))
}, underflow=function(e) {
message("underflow: ", conditionMessage(e))
NA # return value, assigned to xx
})
这些是 S3 类,因此可以具有线性层次结构 --bad
and worse
都是子类error
.
myError <-
function(message, call=NULL, type=c("bad", "worse"))
{
type <- match.arg(type)
class <- c(type, "error", "condition")
structure(list(message=as.character(message), call=call),
class=class)
}
人们还可能创建一个错误,将“simpleError”S3 类扩展为cond <- simpleError("oops"); class(cond) = c("myerr", class(cond)
With tryCatch
我们只需访问单个处理程序,第一个处理程序(在 ?tryCatch 中描述的意义上)匹配条件类
tryCatch({
stop(myError("oops", type="worse"))
}, bad = function(e) {
message("bad error: ", conditionMessage(e))
}, worse = function(e) {
message("worse error: ", conditionMessage(e)) # here's where we end up
}, error=function(e) {
message("error: ", conditionMessage(e))
})
With withCallingHandlers
如果我们不调用重新启动,我们就有机会调用多个处理程序
withCallingHandlers({
stop(myError("oops", type="bad"))
}, bad = function(e) { # here...
message("bad error: ", conditionMessage(e))
}, worse = function(e) {
message("worse error: ", conditionMessage(e))
}, error=function(e) { # ...and here...
message("error: ", conditionMessage(e))
}) # ...and top-level 'error'
withCallingHandlers({
x <- 1
warning(myError("oops", type="bad"))
"OK"
}, bad = function(e) { # here, but continue at the restart
message("bad warning: ", conditionMessage(e))
invokeRestart("muffleWarning")
}, worse = function(e) {
message("worse warning: ", conditionMessage(e))
})
我不太确定你的问题2;我认为这是调用处理程序旨在解决的情况 - 一旦调用重新启动,调用条件的整个框架就准备好等待继续。