R语言变量的延迟绑定和动态绑定

延迟绑定(lazy binding)和动态绑定(active binding)

R语言中,除了一般的变量赋值,还用两种特殊的赋值方式。一种是延迟绑定(lazy binding),还有一种是动态绑定(active binding)。
延迟绑定首次访问变量的时候,进行值的计算(evaluation),而动态绑定时每次访问时,都重新进行值的计算。

实现方式

Base R

延迟绑定

采用delayedAssign(),举个delayedAssign帮助自带的栗子:

delayedAssign("x", {
    for(i in 1:3)
        cat("yippee!\n")
    10
})

x^2 #- yippee
x^2 #- simple number

执行的结果是:

> delayedAssign("x", {
+     for(i in 1:3)
+         cat("yippee!\n")
+     10
+ })
> x^2 #- yippee
yippee!
yippee!
yippee!
[1] 100
> x^2 #- simple number
[1] 100

动态绑定

采用makeActiveBinding(sym, fun, env),举个makeActiveBinding帮助自带的栗子:

# active bindings
f <- local( {
    x <- 1
    function(v) {
        if (missing(v))
            cat("get\n")
        else {
            cat("set\n")
            x <<- v
        }
        x
    }
})

makeActiveBinding("fred", f, .GlobalEnv)   # f 是之前返回的闭包函数
bindingIsActive("fred", .GlobalEnv)
fred
fred <- 2
fred

执行的结果是:

> f <- local( {
+     x <- 1
+     function(v) {
+         if (missing(v))
+             cat("get\n")
+         else {
+             cat("set\n")
+             x <<- v
+         }
+         x
+     }
+ })
> makeActiveBinding("fred", f, .GlobalEnv)
> bindingIsActive("fred", .GlobalEnv)
[1] TRUE
> fred
get
[1] 1
> fred <- 2
set
get
> fred
get
[1] 2

rlang package

package rlang也提供函数

  • env_bind_lazy()
  • env_bind_active()
    完成延迟绑定和动态绑定。使用之前先安装rlang
install.packages("rlang")
library(rlang)

延迟绑定

修改上述的例子:

env_bind_lazy(current_env(), y = {
    for(i in 1:3)
        cat("yippee!\n")
    10
})

y^2 #- yippee
y^2 #- simple number

结果:

> env_bind_lazy(current_env(), y = {
+     for(i in 1:3)
+         cat("yippee!\n")
+     10
+ })
> y^2 #- yippee
yippee!
yippee!
yippee!
[1] 100
> y^2 #- simple number
[1] 100

动态绑定

修改上述的例子:

# active bindings
ff <- local( {
    x <- 1
    function(v) {
        if (missing(v))
            cat("get\n")
        else {
            cat("set\n")
            x <<- v
        }
        x
    }
})

env_bind_active(current_env(), fred = ff)
bindingIsActive("fred", .GlobalEnv)
fred
fred <- 2
fred

执行结果:

> # active bindings
> ff <- local( {
+     x <- 1
+     function(v) {
+         if (missing(v))
+             cat("get\n")
+         else {
+             cat("set\n")
+             x <<- v
+         }
+         x
+     }
+ })
> env_bind_active(current_env(), fred = ff)
> bindingIsActive("fred", .GlobalEnv)
[1] TRUE
> fred
get
[1] 1
> fred <- 2
set
> fred
get
[1] 2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值