我对使用R中的最小代码修改基本函数的方法感兴趣。我知道body
函数将返回任何函数的主体。所以我将body(basefoo)
的输出存储在变量bar
中。想要了解更多关于它是如何工作的,我检查了bar
的类。那是"{"
。我以为这是一个奇怪的课程。我寻找方法,但methods(class="\\{")
,但它说没有方法。
{
类存在的原因是什么?如何修改{
对象或与之交互?
答案 0 :(得分:9)
所有R代码在执行前都会被解析为树(有关详细信息,请参阅Expressions from Advanced R)。为了在树中的任何一点都有多个表达式,R需要创建一个包装器/容器来保存这些表达式。这基本上是{
类代表的内容。它定义了一个代码块。它是要评估的表达式的集合。想想它是否像一个函数,你想要评估的每个表达式都是一个参数(至少它是如何存储在树中的)。代码块只返回最后一个表达式返回的值。比较
as.list(quote({a; b}))
# [[1]]
# `{`
# [[2]]
# a
# [[3]]
# b
as.list(quote(c(a, b)))
# [[1]]
# c
# [[2]]
# a
# [[3]]
# b
看看他们如何在R中变成类似的结构? "功能名称"首先是参数列表。您甚至可以像常规功能一样呼叫{
`{`(a<-1, 5, a+2)
# [1] 3
(注意最后一个值是如何返回的)。另请注意,代码块不会创建自己的作用域,因此如果在控制台上运行,则将在全局环境中定义变量a
。
您只需引用代码块
即可创建此类型的对象class(xx <- quote({a; b}))
# [1] "{"
xx
# {
# a
# b
# }
或建立带引号的电话
class(xx <- as.call(list(quote(`{`), quote(a), quote(b))))
# [1] "{"
xx
# {
# a
# b
# }
并不总是函数的主体属于{
类的情况。例如
x <- function(a) a+1
y <- function(a) {b <- sqrt(a); b+2}
class(body(x))
# [1] "call"
class(body(y))
# [1] "{"
因为我们想在y
函数中运行多个语句,所以我们必须将这些表达式放在代码块中。由于x
只调用一个表达式,因此我们不需要使用{
,因此它具有不同的类。