Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在这种情况下,R和C有什么不同的范围规则?_C#_R_Scope - Fatal编程技术网

C# 在这种情况下,R和C有什么不同的范围规则?

C# 在这种情况下,R和C有什么不同的范围规则?,c#,r,scope,C#,R,Scope,在下面的例子中,有人能指出C和R有哪些不同的作用域规则,从而产生不同的结果吗 C R 使现代化 这个问题很有帮助 我相信我已经发现了区别——在R中,没有文档说块会创建一个新的作用域。所以只有函数才能创建新的作用域,因为循环不能,括号不能 任何人都可以给我一个链接,指向R中的某个明确指南,该指南明确指出,函数以外的括号不会创建新的作用域?我不确定C是否正确,但对于R,函数的评估是惰性的 直到调用函数时,printj中的j才被计算。因此,当您调用funclist[[2]]'foo'时,R才会搜索j的

在下面的例子中,有人能指出C和R有哪些不同的作用域规则,从而产生不同的结果吗

C

R

使现代化 这个问题很有帮助

我相信我已经发现了区别——在R中,没有文档说块会创建一个新的作用域。所以只有函数才能创建新的作用域,因为循环不能,括号不能

任何人都可以给我一个链接,指向R中的某个明确指南,该指南明确指出,函数以外的括号不会创建新的作用域?

我不确定C是否正确,但对于R,函数的评估是惰性的

直到调用函数时,printj中的j才被计算。因此,当您调用funclist[[2]]'foo'时,R才会搜索j的值,上次关闭时,j的值是5。但是,尝试以下操作,您将看到该值与循环完全无关

j <- "Some Other Value"
funclist[[2]]('foo')
关于评论中问题的更新 在R中,for循环不会影响作用域或环境。另一方面,函数和应用程序与循环类似。因此,为了澄清这一点,您不能在嵌套的*环境*内初始化变量并从父环境访问它[1]。然而,你可以做相反的事情;即从子环境中访问父环境的对象

正如罗斯·伊哈卡的标志中清楚地描绘的那样 资料来源:

有关R中作用域的更多信息,请参阅:

[1] 上述说法并不完全正确。您可以使用get..envir=.访问这样的变量。。作用但不能像从嵌套函数内部访问父对象那样直接访问它

我不确定C是否正确,但对于R,函数的计算是惰性的

直到调用函数时,printj中的j才被计算。因此,当您调用funclist[[2]]'foo'时,R才会搜索j的值,上次关闭时,j的值是5。但是,尝试以下操作,您将看到该值与循环完全无关

j <- "Some Other Value"
funclist[[2]]('foo')
关于评论中问题的更新 在R中,for循环不会影响作用域或环境。另一方面,函数和应用程序与循环类似。因此,为了澄清这一点,您不能在嵌套的*环境*内初始化变量并从父环境访问它[1]。然而,你可以做相反的事情;即从子环境中访问父环境的对象

正如罗斯·伊哈卡的标志中清楚地描绘的那样 资料来源:

有关R中作用域的更多信息,请参阅:

[1] 上述说法并不完全正确。您可以使用get..envir=.访问这样的变量。。作用但不能像从嵌套函数内部访问父对象那样直接访问它

我认为C的执行方式是程序性的。所有函数参数都在创建列表时求值

在R中,函数参数仅在第一次调用函数时计算。这意味着当调用funclist[[2]]'foo'时,for循环已经被计算,j的最后一个值为5

注意:可以使用力,这将导致类似C的行为

我认为C的执行方式是程序性的。所有函数参数都在创建列表时求值

在R中,函数参数仅在第一次调用函数时计算。这意味着当调用funclist[[2]]'foo'时,for循环已经被计算,j的最后一个值为5


注意:可以使用力,这将导致类似C的行为

我对R一无所知,但我可以告诉你在C中发生了什么

在C语言中,当您输入一个函数时,您将激活该函数;该激活跟踪该函数调用使用的所有变量和临时值的状态。这就是函数可以递归的方式;每个调用都有自己的激活,因此可以有自己的局部变量值

在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
}
它打印4,因为这是j最后一次使用的值


有关更多详细信息,请参阅。

我对R一无所知,但我可以告诉您在C中发生了什么

在C语言中,当您输入一个函数时,您将激活该函数;该激活跟踪该函数调用使用的所有变量和临时值的状态。这就是函数可以递归的方式;每个调用都有自己的激活,因此可以有自己的局部变量值

在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
}
它打印4,因为这是j最后一次使用的值


有关更多详细信息,请参阅。

对@RicardoSaporta的答案进行一点扩展

在R中运行命令:

environment(funclist[[2]])
您将看到父环境 函数的环境是全局环境,因此,由于j从来都不是函数的局部环境,当函数运行时,它们在局部环境中找不到任何名为j的变量,因此它们接下来要做的是查看封闭环境,即全局环境,并使用j的当前值。如果您执行rmj,那么运行任何函数,您将得到一个它找不到j的错误

如果您希望每个函数都有自己的封闭环境,并具有不同的j值,则可以执行以下操作:

funclist <- list()
for(i in 1:5)
{
   funclist[[i]] <- local( {
    j <- i
    function(x) print(j)
    } )
}

funclist[[2]]('foo') # prints 2

对@RicardoSaporta的答案进行一点扩展

在R中运行命令:

environment(funclist[[2]])
您将看到函数的父环境是全局环境,因此,由于j从来都不是函数的局部环境,当它们运行时,它们在局部环境中找不到任何名为j的变量,因此它们接下来要做的是查看封闭环境,这是全球环境,使用j的当前值。如果您执行rmj,那么运行任何函数,您将得到一个它找不到j的错误

如果您希望每个函数都有自己的封闭环境,并具有不同的j值,则可以执行以下操作:

funclist <- list()
for(i in 1:5)
{
   funclist[[i]] <- local( {
    j <- i
    function(x) print(j)
    } )
}

funclist[[2]]('foo') # prints 2
描述R中变量的作用域规则

第3.5.2节规定

对函数的每次调用都会创建一个框架,其中包含在函数中创建的局部变量,并在一个环境中进行计算,该环境组合起来会创建一个新环境

因此,只有调用函数才能创建新的词法范围。在函数中,您可以通过调用其他函数来创建其他作用域,事实上,对于其唯一目的是创建新作用域的函数,请参阅函数的帮助

<>所以,在C++中的作用域不同于C++,只在函数级,而不是块级。

描述了R.</P>中变量的范围规则。 第3.5.2节规定

对函数的每次调用都会创建一个框架,其中包含在函数中创建的局部变量,并在一个环境中进行计算,该环境组合起来会创建一个新环境

因此,只有调用函数才能创建新的词法范围。在函数中,您可以通过调用其他函数来创建其他作用域,事实上,对于其唯一目的是创建新作用域的函数,请参阅函数的帮助


<>所以在R中的范围不同于C++,只在函数级,而不是块级。

我不熟悉R,但这里有一个澄清的问题。如果你说i@EricLippert,在这种情况下,您将得到值1。R按值复制。问题是,计算函数时的对象j与创建函数时的对象j不同。关于延迟计算的部分也可能会对wrt R有所帮助。我不熟悉R,但这里有一个澄清问题。如果你说i@EricLippert,在这种情况下,您将得到值1。R按值复制。问题是,计算函数时的对象j与创建函数时的对象j不同。关于延迟计算的部分也可能会说明wrt R。在R中,j的范围是什么?需要明确的是,既然这个词被用来表示许多不同的事物,那么j的范围是什么?我的意思是,在程序文本的哪个区域,用名字引用变量j是合法的?您的答案意味着j可以在两个嵌套块内初始化,但可以在外部使用。有多远?j是否在整个程序的作用域内?@EricLippert也许更简洁:假设OP的代码在新的R会话中按原样运行,则可以合法地引用j,即R将查找并返回一个值,而不是在为其赋值后在任何时候抛出错误。那么在j In R之后的任何时候,j的范围是什么?需要明确的是,既然这个词被用来表示许多不同的事物,那么j的范围是什么?我的意思是,在程序文本的哪个区域,用名字引用变量j是合法的?您的答案意味着j可以在两个嵌套块内初始化,但可以在外部使用。有多远?j是否在整个程序的作用域内?@EricLippert也许更简洁:假设OP的代码在新的R会话中按原样运行,则可以合法地引用j,即R将查找并返回一个值,而不是在为其赋值后在任何时候抛出错误。因此,在j之后的任何时候,我可以说在C中,局部变量声明空间总是包含它的作用域,作用域是声明空间w.r.t的子集。变量,因此任何新声明空间的创建都意味着新作用域的创建?如果你愿意,您可以阅读关于R的词法作用域的更多详细信息。@colinfang:对于局部变量声明空间,声明空间和作用域之间有着紧密的关系。对于局部变量而言,可以命名变量的区域和其他任何区域都不可能具有该名称的区域是相同的。这不是事实
e一般而言;类的受保护字段的作用域包括所有子类,但声明空间不包括。我可以说在C中,局部变量声明空间始终包含其作用域作用域是声明空间的子集w.r.t.变量,因此任何新声明空间的创建都意味着新作用域的创建?如果您愿意,您可以阅读关于R的词法作用域的更多详细信息。@colinfang:对于局部变量声明空间,声明空间和作用域之间有着紧密的关系。对于局部变量而言,可以命名变量的区域和其他任何区域都不可能具有该名称的区域是相同的。一般来说,情况并非如此;类的受保护字段的范围包括所有子类,但声明空间不包括。