包/命名空间环境中同一命名函数的值/引用相等性?

SFu*_*n28 11 r

让我们抓住环境"命名空间:统计数据"和"包:统计数据"

ns = getNamespace( "stats" )
pkg = as.environment( "package:stats" )
Run Code Online (Sandbox Code Playgroud)

现在让我们在两者中获得"sd"函数:

nsSd = get( "sd" , envir = ns , inherits = FALSE )
pkgSd = get( "sd" , envir = pkg , inherits = FALSE )
Run Code Online (Sandbox Code Playgroud)

它们是一样的吗?他们是!但"同样"是什么意思呢?参考或价值平等?

identical( nsSd , pkgSd )
Run Code Online (Sandbox Code Playgroud)

这意味着引用相等,因为以下返回FALSE:

test1 = function() {}
test2 = function() {}
identical( test1 , test2 )
Run Code Online (Sandbox Code Playgroud)

但如果这是真的,那就意味着Environment的框架可以包含函数指针和函数对象.使问题进一步复杂化的是,函数可以在一个环境中"生存",但可以告诉函数其执行环境是另一个环境.钱伯斯SoDA似乎没有答案(它是一本密集的书,也许我错过了!)

所以,我想要一个明确的答案.以下哪项是正确的?或者这里是否有错误的三分法?

  1. nsSd并且pkgSd是两个不同的对象(尽管是彼此的副本),其中对象pkgSd具有ns作为其执行环境
  2. nsSdpkgSd指向同一个对象.
  3. nsSd是一个指针,pkgSd因此它们被视为相同

Ric*_*ton 5

它们是指向同一对象的指针.使用这个答案来解决另一个问题,我们可以检查两个对象是否指向内存中的相同位置.

are_same <- function(x, y)
{
  f <- function(x) capture.output(.Internal(inspect(x)))
  all(f(x) == f(y))
}

are_same(nsSd, pkgSd) #TRUE
are_same(1:5, 1:5)    #FALSE
Run Code Online (Sandbox Code Playgroud)

  • 非常酷的功能.直到现在,我还不知道当我做`j < - rnorm(1e7); k < - j`,`j`和`k`只是指向同一内存位置的指针.但是当我执行`k [1] < - 1`时,整个向量`k`需要被复制到一个新位置,因为它现在不同了.所以`k < - j`比`k [1] < - 1`快得多.一个很好的服务R核心为我们提供了,直到现在我甚至都不喜欢它! (3认同)
  • @JoshO'Brien:是的,虽然R假装总是按价值传递东西,但为了获得更好的性能,它确实只是在它可以逃脱它时传递对象的引用. (2认同)