有人可以指出 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 中,没有文档说一个 block 会创建一个新的作用域。所以只有函数可以创建一个新的作用域,for 循环不能,括号不能。
任何人都可以给我一个指向 R 中一些权威指南的链接,该指南明确指出除函数之外的括号不会创建新范围?
最佳答案
我不确定 C#
,但对于 R
,函数是惰性求值的。
print(j)
中的 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=..)
函数访问这样的变量。但是您不能像从嵌套函数内部访问父对象的方式那样直接访问它。
关于c# - 在这种情况下,R 和 C# 的作用域规则有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16239126/