在面向对象的 R 编程(尤其是 Winston Chang 的 R6 包)中,什么是主动绑定?
2 回答
首先,最好了解什么是“绑定”。如果我们运行如下代码:
x <- 5
那么在计算机内部发生的事情是我们将 5 的值放入内存槽中,并且我们还将名称“x”“绑定”到该位置和值,以便稍后我们可以使用x
它会转到那个位置内存位置并查找值(在我们将其更改为其他值之前为 5)。这称为静态绑定,因为除非程序专门进行更改,否则值不会更改。
主动绑定的相似之处在于,我们将变量名(如“x”)绑定到某物,但某物不仅仅是一个常量值,而是一个每次我们尝试访问时都会运行的函数x
。因此,您可以将名称“x”绑定到调用的函数,rnorm
然后每次访问x
时都会看到不同的随机正常值。
另一个例子,考虑我们是否对静态绑定做一些事情,比如:
mydf <- data.frame( x=1:10, y=10:1 )
df.size <- nrow(mydf)
mydf <- data.frame(z=1:100)
现在变量df.size
具有mydf
创建时的行数,而不是现在的行数(由于nrow
运行一次,因此结果作为静态绑定放入df.size
变量中,它不会随着数据框的更改而更新)。另一方面,如果我们在df.size
和一个运行的函数之间创建了一个活动绑定,nrow(mydf)
那么任何时候我们查看它的“值”,无论我们更改多少次df.size
,它都会显示当前的行数。mydf
1) R在 R 中,主动绑定的想法是您可以定义一些看起来像变量但实际上每次访问它时都会调用一个函数的东西。
例如,在makeActiveBinding
下面的语句每次randomNo
用作变量之后,它调用第二个参数中指定的函数makeActiveBinding
(在这种情况下生成一个正常的随机变量)并返回函数的值:
makeActiveBinding("randomNo", function() rnorm(1), .GlobalEnv)
set.seed(123) # for reproducibility
randomNo
## [1] -0.5604756
randomNo
## [1] -0.2301775
2) R6类似地,在 R6 中,活动绑定看起来像一个字段,但在访问时它实际上运行一个函数,并返回函数的值。
这是 (1) 中使用 R6 活动绑定重做的示例。请注意,每次randomNo
访问该字段时,都会调用相关函数(生成正常的随机变量)并将其值作为该字段的值返回。
library(R6)
RandomClass <- R6Class("Numbers",
active = list(
randomNo = function() rnorm(1)
)
)
set.seed(123)
randomObject <- RandomClass$new()
randomObject$randomNo
## [1] -0.5604756
randomObject$randomNo
## [1] -0.2301775
3) R6 - 第二个例子 另一个例子可以在 这里的 R6 主动绑定文档中找到。在该示例中,每次访问该字段时x2
就像访问普通字段一样,都会调用与关联的函数x2
(不向其传递任何参数),并且值x2
是运行该函数的结果。