有人可以指出C#和R在哪个范围规则上有所不同,以便在以下示例中产生不同的结果吗?

C#

public static void Main(string[] args)
{
    var funs = new Action<string>[5];
    for (int i = 0; i < 5; i++)
    {
        int j = i;
        {
            funs[j] = x => Console.WriteLine(j);
        }
    }
    funs[2]("foo"); // prints 2
}


[R

funclist <- list()
for(i in 1:5)
{
  {
    j<-i
    funclist[[j]] <- function(x) print(j)
  } // the 5 inner blocks share the same scope?
}

funclist[[2]]('foo') // prints 5


更新资料

这个问题很有帮助R: usage of local variables

我相信我发现了区别-在R中没有文档说一个块会创建一个新的作用域。因此,只有函数可以创建新的作用域,而for循环不能,方括号不能。

任何人都可以给我链接到R中的一些权威指南,该指南明确指出功能以外的方括号不会创建新的作用域?

最佳答案

我不确定C#,但是对于R,这些函数的计算是惰性的。

在调用该函数之前,j中的print(j)不会被求值。因此,当您仅调用funclist[[2]]('foo')时,R才搜索j的值,该值最后一次保留为5。但是,请尝试以下操作,您会发现该值与以下位置的循环无关所有。

j <- "Some Other Value"
funclist[[2]]('foo')


有关评论中问题的更新

R中,for循环不会影响作用域或环境。 (另一方面,functionsapply就像循环一样)。因此,为了澄清起见,您不能在嵌套*环境*内初始化变量并从父环境[1]访问它。但是,您可以做相反的事情;从子级环境中访问父级环境的对象。

这张照片清楚地描绘了罗斯·伊卡(Ross Ihaka)的星座

来源:http://www.nytimes.com/2009/01/07/technology/business-computing/07program.html?pagewanted=all

有关R中作用域的更多信息,请参见:
 http://cran.r-project.org/doc/contrib/Fox-Companion/appendix-scope.pdf

[1]以上陈述并非完全正确。您可以使用get(.., envir=..)函数访问此类变量。但是,您不能以从嵌套函数内部访问父对象的方式直接访问它。

07-28 03:04
查看更多