是```一堂课?

时间:2018-05-22 17:33:55

标签: r oop

我对使用R中的最小代码修改基本函数的方法感兴趣。我知道body函数将返回任何函数的主体。所以我将body(basefoo)的输出存储在变量bar中。想要了解更多关于它是如何工作的,我检查了bar的类。那是"{"。我以为这是一个奇怪的课程。我寻找方法,但methods(class="\\{"),但它说没有方法。

{类存在的原因是什么?如何修改{对象或与之交互?

1 个答案:

答案 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只调用一个表达式,因此我们不需要使用{,因此它具有不同的类。