local()如何区别于R中的其他闭包方法? [英] How does local() differ from other approaches to closure in R?

查看:156
本文介绍了local()如何区别于R中的其他闭包方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

昨天我从Bill Venables学到了local()如何帮助创建静态函数和变量,例如

Yesterday I learned from Bill Venables how local() can help create static functions and variables, e.g.,

example <- local({
  hidden.x <- "You can't see me!"
  hidden.fn <- function(){
    cat("\"hidden.fn()\"")
  }
  function(){
    cat("You can see and call example()\n")
    cat("but you can't see hidden.x\n")
    cat("and you can't call ")
    hidden.fn()
    cat("\n")
  }
})

,其行为如下:

> ls()
[1] "example"
> example()
You can see and call example()
but you can't see hidden.x
and you can't call "hidden.fn()"
> hidden.x                 
Error: object 'hidden.x' not found
> hidden.fn()
Error: could not find function "hidden.fn"



R中的静态变量中讨论过这种事情,其中​​采用了不同的方法。

I've seen this kind of thing discussed in Static Variables in R where a different approach was employed.

这两种方法的利弊是什么?

What the pros and cons of these two methods?

推荐答案

strong>

Encapsulation

这种编程风格的优点是隐藏的对象不会被任何其他对象覆盖,所以你可以更自信的包含你的想法。它们不会被错误地使用,因为它们不能被容易地访问。在问题的链接到的帖子中有一个全局变量, count ,可以从任何地方访问和覆盖,所以如果我们调试代码,看看 count 并看到它的改变,我们不能真正地确定代码的哪部分改变了它。相反,在问题的示例代码中,我们更有保证不涉及代码的其他部分。

The advantage of this style of programming is that the hidden objects won't likely be overwritten by anything else so you can be more confident that they contain what you think. They won't be used by mistake since they can't readily be accessed. In the linked-to post in the question there is a global variable, count, which could be accessed and overwritten from anywhere so if we are debugging code and looking at count and see its changed we cannnot really be sure what part of the code has changed it. In contrast, in the example code of the question we have greater assurance that no other part of the code is involved.

请注意,我们实际上可以访问隐藏的函数,不太容易:

Note that we actually can access the hidden function although its not that easy:

# run hidden.fn
environment(example)$hidden.fn()

面向对象编程

还要注意,这非常接近面向对象编程,其中示例 hidden.fn 是方法, hidden.x 是一个属性。我们可以这样做,使其显式:

Also note that this is very close to object oriented programming where example and hidden.fn are methods and hidden.x is a property. We could do it like this to make it explicit:

library(proto)
p <- proto(x = "x", 
  fn = function(.) cat(' "fn()"\n '),
  example = function(.) .$fn()
)
p$example() # prints "fn()"

proto不隐藏 x fn ,但是它不是那么容易访问它们的错误,因为你必须使用 p $ x p $ fn()来访问它们并不是能够写 e <例); e $ hidden.fn()

proto does not hide x and fn but its not that easy to access them by mistake since you must use p$x and p$fn() to access them which is not really that different than being able to write e <- environment(example); e$hidden.fn()

编辑:

面向对象的方法确实增加了继承的可能性,例如可以定义 p 的子项,它的行为类似于 p ,除了它覆盖 fn

The object oriented approach does add the possibility of inheritance, e.g. one could define a child of p which acts like p except that it overrides fn.

ch <- p$proto(fn = function(.) cat("Hello from ch\n")) # child
ch$example() # prints: Hello from ch

这篇关于local()如何区别于R中的其他闭包方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆