MrF*_*ick 10
在执行之前,所有R代码都会被解析为树(有关详细信息,请参阅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
Run Code Online (Sandbox Code Playgroud)
看看他们如何在R中变成类似的结构?"函数名称"首先跟随参数列表.你甚至可以{像常规功能一样打电话
`{`(a<-1, 5, a+2)
# [1] 3
Run Code Online (Sandbox Code Playgroud)
(注意最后一个值是如何返回的).另请注意,代码块不会创建自己的作用域,因此a如果在控制台上运行此变量,则会在全局环境中定义该变量.
您可以通过引用代码块来创建此类型的对象
class(xx <- quote({a; b}))
# [1] "{"
xx
# {
# a
# b
# }
Run Code Online (Sandbox Code Playgroud)
或者用带引号的符号建立一个电话
class(xx <- as.call(list(quote(`{`), quote(a), quote(b))))
# [1] "{"
xx
# {
# a
# b
# }
Run Code Online (Sandbox Code Playgroud)
并且情况并非总是如此.函数的主体将是{类.例如
x <- function(a) a+1
y <- function(a) {b <- sqrt(a); b+2}
class(body(x))
# [1] "call"
class(body(y))
# [1] "{"
Run Code Online (Sandbox Code Playgroud)
因为我们想在y函数中运行多个语句,我们必须将这些表达式放在代码块中.因为x只调用一个我们不需要使用的表达式{所以它有一个不同的类.