有人可以指出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循环不会影响作用域或环境。 (另一方面,functions
和apply
就像循环一样)。因此,为了澄清起见,您不能在嵌套*环境*内初始化变量并从父环境[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=..)
函数访问此类变量。但是,您不能以从嵌套函数内部访问父对象的方式直接访问它。