Hadley 的“Advanced R”让我们简要了解函数式编程和“函数运算符”的可能应用。然而,我担心的是我要么不完全理解这些如何简化代码,要么不情愿地通过使用其他解决方案来遵循一些不好的做法。
我没有创建期望输入是函数的运算符,而是创建了一个包装器,它将一个表达式作为其参数,并返回一个完整的输出(而不是一个仍然需要调用的函数)。见示例:
# function operator
delay_by <- function(delay, f) {
function(...) {
Sys.sleep(delay)
f(...)
}
}
# simple wrapper
delay_by2 <- function(expr, delay) {
Sys.sleep(delay)
eval(expr)
}
delay_by(1, sqrt)(2)
delay_by2(sqrt(2), 1)
operator <- delay_by(1, sqrt)
wrapper <- function(x) delay_by2(sqrt(x), 1)
operator(2)
wrapper(2)
这种方法仍然允许输入泛函(sapply 等)并应用内存。此外,这支持管道 %>%
.lapply(1:10, function(x) sqrt(x) %>% delay_by2(1))
此解决方案的潜在缺点是它没有创建持久执行环境来存储维护函数状态的变量,但可以使用 <<- new.env()
显式创建这些变量。 .有什么理由让我认为我的方法低劣吗?我试图避免不必要的嵌套。
最佳答案
测试和打包,表达式不多。所以如果你使用一个
函数方法可以编写单元测试,并将其放入包中。
使用 eval 方法,您仅限于自己的 REPL 测试。显然我们都应该做“测试驱动开发”,至少在我们的生产代码上,什么都不应该出去
没有一组覆盖尽可能多的代码的单元测试
经济上可行。这让人们的生活变得更轻松
(包括你)谁可能有一天需要做出改变。
在其他语言中,但我不太了解 R 的编译器
可以对此发表任何看法。
一定的复杂性。另一方面,使用函数可以让您
逻辑增长到任何实际规模。
eval
作为一个构造体是一个非常强大的构造体,但它会给你带来麻烦,有点像使用高功率激光Papercut 。由于它通常易于实现,因此它存在于许多
语言,网上有很多关于它为什么危险的文章——你应该看看它们。所以像那个高功率激光,你不应该真的得到
习惯使用它,除非有必要。
关于r - R 中的函数运算符和函数包装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42054590/