首页 > 解决方案 > 列表中的函数可以访问 R 中列表的属性吗?

问题描述

在以下示例中,列表中的函数应返回字符串"The value currently is 42"

l <- list(
  param = 42,
  f = function() { paste("The value currently is", param) }
)

(示例灵感来自 Mozilla 的关键字this的 js 文档)

显然调用l$f()失败是因为object 'param' not found.

ls.str()我尝试使用和检查环境中可用的对象ls()。我找到的最接近的解决方案是引用分配给列表的变量名称。

l <- list(
  param = 42,
  f = function() { paste("The value currently is", l$param) }
)

这当然不是最理想的,因为变量可以命名为任何东西。

里面的函数有没有办法l引用它的相邻属性param?如果没有,是否有一些嵌套的更复杂的解决方案可以完成类似的任务?

标签: rlistfunctionreference

解决方案


您可以match.call在函数内部使用从用于访问函数的子集调用中捕获列表的名称。如果您eval在父框架中使用此符号,则您有一个 (dereferenced) 的等价物this

这给出了所需的行为,如以下表示所示:

l <- list(a = 1, 
          f = function() {
            mc <- match.call()
            this_sym <- as.list(as.list(mc)[[1]])[[2]]
            this <- eval(this_sym, envir =  parent.frame())
            cat("Value of ", as.character(this_sym), "$a is ", this$a, sep ="")
          })

l$f()
#> Value of l$a is 1

l$a <- 42

l$f()
#> Value of l$a is 42

new_list <- l

new_list$f()
#> Value of new_list$a is 42

然而,这感觉就像是在尝试使用一个普通的列表来复制那种已经可以用 R6 或 S4 类做得更好的面向对象编程。

reprex 包(v0.3.0)于 2020-07-17 创建


推荐阅读