【发布时间】:2013-06-26 10:29:30
【问题描述】:
我对 R 相当陌生,在阅读手册时,我偶然发现了一段关于词法作用域的文章以及以下代码示例:
open.account <- function(total) {
list(
deposit = function(amount) {
if(amount <= 0)
stop("Deposits must be positive!\n")
total <<- total + amount
cat(amount, "deposited. Your balance is", total, "\n\n")
},
withdraw = function(amount) {
if(amount > total)
stop("You don't have that much money!\n")
total <<- total - amount
cat(amount, "withdrawn. Your balance is", total, "\n\n")
},
balance = function() {
cat("Your balance is", total, "\n\n")
}
)
}
ross <- open.account(100)
robert <- open.account(200)
ross$withdraw(30)
ross$balance()
robert$balance()
ross$deposit(50)
ross$balance()
ross$withdraw(500)
所以,我明白上面的代码是做什么的,我想我仍然对它的工作原理感到困惑。如果在函数执行完成后您仍然可以访问函数的“局部”变量,那么预测何时不再需要变量不是很难或不可能吗?在上面的代码中,如果它被用作更大程序的一部分,“total”是否会保存在内存中,直到整个程序完成?(本质上成为一个全局变量内存)如果这是真的,不会这会导致内存使用问题吗?
我在这个网站上查看了另外两个问题:“词法作用域是如何实现的?”和“为什么编译器更喜欢词法范围?”。那里的答案在我脑海中浮现,但它让我想知道:如果(正如我猜测的那样)编译器不仅使所有变量全局化(内存方面),而是使用某种技术来预测某些变量何时不会不再需要并且可以删除,这样做实际上不会使编译器更难而不是更容易吗?
我知道这是很多不同的问题,但任何帮助都会很好,谢谢。
【问题讨论】:
-
total在此实例中是一个全局变量,因为您使用了<<-运算符,请参阅?"<<-"。您应该能够在交互式会话中直接检查total。相反,如果您使用<-,它在函数执行后将不可用,但它也会破坏这个特定的函数。 -
R 确实将其所有变量都存储在内存中。这确实会导致大型数据集的内存问题。这就是为什么会有像
bigdata、bigmemory、ff、data.table等这样的包来解决 R 的一些设计限制。您可以做的其他事情是将数据集存储在数据库中,并仅在必要时查询它们;见RODBC、DBI、RMySQL、SQLite等等。 -
@Justin Umm 不太清楚你的意思,但 R 帮助文档说
-
@HongOoi 哦,好吧,我想这回答了我想知道的主要问题。谢谢!
-
@Katana,基本上,为评估函数“调用”而创建的环境只有在评估完成后没有对对象的引用时才会被破坏。有关更多信息,请参阅github.com/hadley/devtools/wiki/Environments 和相关链接。
标签: r variables scope lexical lexical-scope