"调用"中空参数的表示

Eva*_*Aad 1 reflection r argument-passing

什么样的动物是空洞的争论?考虑以下代码.

> f <- function(...) match.call()
> l <- as.list(f(,3))
> l
[[1]]
f

[[2]]


[[3]]
[1] 3

> typeof(l[[2]])
[1] "symbol"

> identical(l[[2]],``)
Error: attempt to use zero-length variable name

> as.character(l[[2]])
[1] ""
Run Code Online (Sandbox Code Playgroud)

那是什么巫术?

Eva*_*Aad 6

如果看起来像是l[[2]]一个特殊的对象:空符号.关于空符号的一些事实(基于随意实验推测).

(1)空符号是符号:

> is.symbol(l[[2]])
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

(2)无法明确创建空符号:

> as.name("")
Error in as.name("") : attempt to use zero-length variable name
> ``
Error: attempt to use zero-length variable name
> quote()
Error in quote() : 0 arguments passed to 'quote' which requires 1
Run Code Online (Sandbox Code Playgroud)

(3)创建空符号的唯一方法是通过quote函数调用并传递一个空参数,例如:

> c <- quote(f(,0))
> d <- quote(f(x, n=, 0))
Run Code Online (Sandbox Code Playgroud)

空符号现在可以这样访问:c[[2]],d$n,as.list(d)[[3]]

(4)空值是唯一的,不等于任何其他符号:

> identical(c[[2]], d$n)
[1] TRUE

> identical(c[[2]], `a`)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

(5)空符号不能分配给独立变量.如果分配给这样的变量,则该变量实际上被赋予"缺少参数"值:

> x <- d$n
> missing(x)
[1] TRUE
> missing(d$n)
Error in missing(d$n) : invalid use of 'missing'
Run Code Online (Sandbox Code Playgroud)

但是,可以将空符号分配给列表槽:

> p <- list(`a`, k=`b`)
> p[[1]] <- d$n
> p$k <- c[[2]]

> identical(p[[1]], d$n)
[1] TRUE

> identical(p[[1]], p[[2]])
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

它可以作为函数参数传递:

> h <- function(x) identical("", d$n)
> h(c[[2]])
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

作为函数参数传递时,不认为该参数丢失:

> h2 <- function(x) missing(x)
> h2(c[[2]])
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

但比较一下

> h2(x)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

(6)空符号的字符值是空字符串:

> identical("", as.character(d$n))
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

(7)没有原始函数检查值是否为空符号.要检查值是否为空符号,需要将其字符表示与空字符串进行比较:

> is.symbol(d$n) && identical("", as.character(d$n))
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

附录

以下是一些函数定义,以便于创建和识别空符号和"缺少参数"对象.

> isEmptySymbol
function(x) is.symbol(x) && identical("", as.character(x))

> EmptySymbol
function() (quote(f(,)))[[2]]

> isMissingArgObject
function(x) {
if ("x" %in% names(match.call())) return (missing(x))
stop("An argument must be supplied.") }

> MissingArgObject
function() quote(expr=)
Run Code Online (Sandbox Code Playgroud)