R中的rlang中expr和exprs的类不同!为什么?

我不确定这里是否有这个问题,但我在这里很困惑.我正在阅读这本名为Advanced R的书,由Hadley Wickham从
here开始.

这里有一个名为水泥的功能,我对它进行了一些修改并试图理解它.

library(rlang)
cement1 <- function(x) {
  dots <- expr(x)
  print(class(dots))
  #paste(expr_name(x))
}

cement2 <- function(y,z) {
  dots <- exprs(y,z)
  print(class(dots))
  #paste(purrr::map(dots, expr_name), collapse = " ")
}

在没有任何参数的情况下运行上面的cement1会将我的点类返回为“name”.

但是,当我使用附加参数运行cement2函数时,类返回“list”,{简单地将class(expr(x))返回“name”而class(exprs(x))返回“list”}.

我没有理解这个为什么它打印由expr和exprs返回的不同类.我认为我知道的唯一区别是,一个处理一个参数,另一个处理多个参数,但我可能错了,我可能错过了一些细节.

原始问题:所以,这一切都是通过在我运行函数时删除代码中的comments1和cement2的单独运行这两个函数来开始的.下面是它们返回的输出:

cement1(Hello) #Returns , Error in type_of(.x) : object 'Hello' not found 
cement2(Hello) #Works very well and returns, [1] "y z"

所以我试图找出为什么cement1失败然后打印他们的类,这是我意识到,expr和exprs返回不同的类.

我的问题是:

1)它们是否按设计,如果是,那为什么?或者,我正在做一些可怕的错误,我目前无法看到.

2)如果没有,水泥1不能正常工作,这是正确的方法吗?

我很抱歉句子太长,我的第一语言不是英语,所以如果有什么傻话,请告诉我,我会纠正它.我希望这不是重复,我试图找到答案,但我自己找不到.

谢谢你的帮助.

R版本:3.4.2
琅勃拉邦:0.2.0

最佳答案 1)是的,expr和exprs的返回值因设计而异.从?expr帮助页面:

enexpr() and expr() capture a single raw expression.

enexprs() and exprs() capture a list of raw expressions including expressions contained in ....

2)expr_name()需要一个带引号的表达式,例如expr()产生的表达式.因此,您需要修改您的cement1以在点上调用expr_name(),而不是x.您也可以删除粘贴,因为您没有连接任何内容.

cement1 <- function(x) {
  dots <- expr(x)
  # print(class(dots))      ## Commented out for clarity
  expr_name(dots)           ## The input to expr_name is now effectively expr(x)
}
cement1( Hello )
# "x"

你的函数cement2基本上在exprs()返回的列表的每个元素上调用expr_name(),然后将结果连接成一个字符串.

2a)现在我们让你的水泥1工作了,我们可以进一步改进它.目前,该函数不使用其输入参数x. expr()只是捕获未评估的表达式,并且无论您为参数命名什么,此表达式将始终为x:

cement1.1 <- function( completelyIgnoredName ) {
  dots <- expr(x)
  expr_name(dots)
}
cement1.1( Hello )
# "x"

但是,如果用enexpr()替换expr(),该函数将替换作为函数参数提供的表达式,并将其捕获:

cement1.2 <- function(x) {
  dots <- enexpr(x)
  expr_name(dots)
}
cement1.2( Hello )
# "Hello"
点赞