在R中编写函数的常规方法(据我所知)是避免副作用,并从函数返回一个值。
contained <- function(x) {
x_squared <- x^2
return(x_squared)
}
在这种情况下,返回的是函数的输入值,但变量x_squared
不可用。
但是,如果你需要违反这个基本的函数式编程原则(我不确定R对这个问题有多认真),并从一个函数返回一个对象,你有两个选择。
escape <- function(x){
x_squared <<- x^2
assign("x_times_x", x*x, envir = .GlobalEnv)
}
对象x_squared
和x_times_x
都被返回。一种方法比另一种方法更可取吗?为什么?
3条答案
按热度按时间mdfafbf11#
托马斯Lumley回答了这个问题in a superb post on r-help the other day。
<<-
是关于封闭环境的,所以你可以这样做(我再次引用他4月22日的帖子in this thread):<<-
作为词法作用域的“超级赋值”是合理的用法,而不是简单地在全局环境中赋值。为此,托马斯有以下几个选择词:邪恶和错误的用法是修改全局环境中的变量。
非常好的建议。
wfsdck302#
根据手册第here页、
运算符
<<-
和->>
导致在环境中搜索被赋值变量的现有定义。我在实践中从来没有这样做过,但在我看来,
assign
在精确指定环境方面赢得了很多分数,甚至不必考虑R的作用域规则。<<-
在环境中执行搜索,因此有点难以解释。编辑:为了尊重@Dirk和@Hadley,听起来
assign
是实际分配到全局环境的适当方式(当你知道你想要的时候),而<<-
是“提升”到更广泛范围的适当方式。gkn4icbw3#
正如@John在他的回答中指出的,assign允许您具体指定环境。具体应用如下:
这里我们同时使用了
<<-
和assign
。注意如果你想用<<-
来赋值给顶层函数的环境,你需要声明/初始化变量。但是,对于assign
,你可以用parent.frame(1)
来指定封装环境。