2016-12-28 119 views
1

我在理解为什么在R中,下面的两个函数functionGen1functionGen2行为不同。这两个函数都试图返回另一个函数,它只是将作为参数传递给函数发生器的数字打印出来。了解R函数懒惰评估

在第一个例子中,生成的函数失败,因为a不再存在于全局环境中,但我不明白它为什么需要。我会认为它是作为参数传递的,并且在生成器函数的名称空间和打印函数中替换为aNumber

我的问题是:为什么list.of.functions1列表中的功能在全球环境中未定义a时不再起作用? (为什么这对list.of.functions2甚至list.of.functions1b的情况下工作?

functionGen1 <- function(aNumber) { 
    printNumber <- function() { 
    print(aNumber) 
    } 
    return(printNumber) 
} 

functionGen2 <- function(aNumber) { 
    thisNumber <- aNumber 
    printNumber <- function() { 
    print(thisNumber) 
    } 
    return(printNumber) 
} 

list.of.functions1 <- list.of.functions2 <- list() 
for (a in 1:2) { 
    list.of.functions1[[a]] <- functionGen1(a) 
    list.of.functions2[[a]] <- functionGen2(a) 
} 

rm(a) 

# Throws an error "Error in print(aNumber) : object 'a' not found" 
list.of.functions1[[1]]() 

# Prints 1 
list.of.functions2[[1]]() 
# Prints 2 
list.of.functions2[[2]]() 

# However this produces a list of functions which work 
list.of.functions1b <- lapply(c(1:2), functionGen1) 

回答

3

更小例子:

functionGen1 <- function(aNumber) { 
    printNumber <- function() { 
    print(aNumber) 
    } 
    return(printNumber) 
} 

a <- 1 
myfun <- functionGen1(a) 
rm(a) 
myfun() 
#Error in print(aNumber) : object 'a' not found 

你的问题不是关于命名空间(这是关系到包装一个概念),但有关的变量范围和懒惰的评价。

懒惰评估意味着函数参数仅在需要时才被评估。在您致电myfun之前,没有必要评估aNumber = a。但由于a已被删除,此评估失败。

通常的解决办法是强制评估明确,你与你的functionGen2或者,例如,

functionGen1 <- function(aNumber) { 
    force(aNumber) 
    printNumber <- function() { 
    print(aNumber) 
    } 
    return(printNumber) 
} 

a <- 1 
myfun <- functionGen1(a) 
rm(a) 
myfun() 
#[1] 1 
+0

谢谢!将接受答案并更改问题的题目以提供懒惰评估。这让我沮丧,现在知道要搜索什么。 – kabdulla

+0

如果您不知道这个词,那么您应该查看“关闭”,因为这是您在那里创建的内容。 – Roland