< - 和<<之间的区别 -

cry*_*nic 3 r lexical-scope

情况1:

rm(list = ls())
foo <- function(x = 6){
  set <- function(){
  x <- x*x}
  set()
x}
foo()
# [1] 6
Run Code Online (Sandbox Code Playgroud)

案例2:

rm(list = ls())
foo <- function(x = 6){
set <- function(){
  x <<- x*x}
  set()
  x}
foo()
# [1] 36
Run Code Online (Sandbox Code Playgroud)

我读到该<<-运算符可用于为与当前环境不同的环境中的对象赋值.它表示<<-可以对不在当前环境中的对象进行对象初始化.我想问一下可以使用哪个环境的对象进行初始化<<-.在我的情况下环境是foo功能环境,可以<<-初始化函数外部的对象或当前环境中的对象吗?完全混淆何时使用<-以及何时使用<<-.

Tim*_*sen 8

运算符<<-是父作用域赋值运算符.它用于将最近的父作用域中的变量赋值给它所评估的作用域.因此,这些分配"粘在"函数调用之外的范围内.请考虑以下代码:

fun1 <- function() {
    x <- 10
    print(x)
}

> x <- 5    # x is defined in the outer (global) scope
> fun1()
[1] 10      # x was assigned to 10 in fun1()
> x
[1] 5       # but the global value of x is unchanged
Run Code Online (Sandbox Code Playgroud)

在函数中fun1(),将为该值分配局部变量,但在全局范围内,不会更改值.现在考虑重写函数以使用父作用域赋值运算符:x10x

fun2 <- function() {
    x <<- 10
    print(x)
}

> x <- 5
> fun2()
[1] 10      # x was assigned to 10 in fun2()
> x
[1] 10      # the global value of x changed to 10
Run Code Online (Sandbox Code Playgroud)

因为函数fun2()使用<<-运算符,所以x在函数完成评估后分配"stick".R实际上做的是遍历所有范围外部fun2()并查找包含变量的第一个范围x.在这种情况下,唯一的范围fun2()是全局范围,因此它在那里进行分配.

正如一些人已经评论过的那样,<<-操作员对许多人不满意,因为它可以打破R脚本的封装.如果我们将R函数视为一个独立的功能,则不应该允许它干扰调用它的代码的状态.滥用<<- 赋值运算符会冒这样做的风险.