3

我一直在玩 R6 ab bit 并尝试实现一个替换功能(在精神上类似于base::`diag<-`())。得知以下内容不起作用,我并不感到惊讶

library(R6)

r6_class <- R6Class("r6_class",
  public = list(
    initialize = function(x) private$data <- x,
    elem = function(i) private$data[i],
    `elem<-` = function(i, val) private$data[i] <- val
  ),
  private = list(
    data = NULL
  )
)

test <- r6_class$new(1:5)
test$elem(2)
#> [1] 2
test$elem(2) <- 3
#> Error in test$elem(2) <- 3 :
#>  target of assignment expands to non-language object

这在前缀表示法中对应什么?以下所有工作都按预期工作,所以我想这些都不是

test$`elem<-`(2, 3)
`$`(test, "elem<-")(2, 3)

我对可能的解决方法不太感兴趣,但更想了解为什么上述内容无效。

4

1 回答 1

0

您可以有嵌套的复杂分配,例如

names(x)[3] <- "c"

test$elem(2) <- 3

不是那种形式。这将是合法的语法

elem(test,2) <- 3

这将扩展到

*tmp* <- test
test <- `elem<-`(*tmp*, 2, 3)

但在原始形式中,它必须扩展为

*tmp* <- 2
2 <- `test$elem<-`(*tmp*, 3)

(我用test$elem<-反引号表示它是由 . 返回的函数的赋值版本test$elem。这不太对,没有这样的东西。)主要问题是被修改的对象是2,所以你得到你看到的错误消息: 不允许修改2

如果你想在 R6 中这样做,我认为你可以这样做。定义一个全局函数

`elem<-` <- function(x, arg, value) x$`elem<-`(arg, value)

elem<-并将您的类方法的定义更改为

`elem<-` = function(i, val) { private$data[i] <- val; self }

每个分配方法都需要两个定义并不是那么方便,但它似乎工作。

于 2019-08-22T21:56:19.900 回答