我有一個全局變量x
,並且想要構建函數f
,該函數在函數創建時返回值x
。例如:在函數定義中使用全局變量的當前值
x <- 5
f <- function() return(x)
f()
> 5
x <- 10
f()
> 10 # Should return 5
我想一個函數總是返回5
(或任何的x
值是在函數創建時),而不使用其他的全局變量。那可能嗎?
我有一個全局變量x
,並且想要構建函數f
,該函數在函數創建時返回值x
。例如:在函數定義中使用全局變量的當前值
x <- 5
f <- function() return(x)
f()
> 5
x <- 10
f()
> 10 # Should return 5
我想一個函數總是返回5
(或任何的x
值是在函數創建時),而不使用其他的全局變量。那可能嗎?
單獨使用全局變量是不可能的。當函數被定義時,函數體中的變量都不會被實際評估,直到函數被調用。你想要的東西似乎是在創作時保持價值的封閉。而是寫一個函數返回一個函數
x <- 5
getfun <- function() {z<-x; function() return(z)}
f <- getfun()
x<- 10
g <- getfun()
f()
# [1] 5
g()
# [1] 10
甚至更好,不要隱式地使用全局變量。創建一個函數,一組特定的參數,並返回一個新的功能
returnVal <- function(x) {force(x); function() return(x)}
f<-returnVal(5)
g<-returnVal(10)
f()
# [1] 5
g()
# [1] 10
1)這節省了X第一次F稱值,然後利用x的值,即使x已經被改變下一次f被調用。在本地環境中創建f並將f放置在該環境中。如果x以前不在那裏,現在就是。如果它以前在那裏,那麼它將被檢索並放回。結果是總會使用遇到的第一個x。
f <- local(function() {
p <- parent.env(environment())
p$x <- x
x
})
x <- 5
f()
## [1] 5
x <- 10
f()
## [1] 5
2)在評論@Konrad和@Frank建議以下變化中,我們根據f刪除分配,並把它在當地。
從功能的用戶角度來看,有一點不同。在函數定義時,這會實例化x的值,而(1)在第一次調用函數時實例化x,如果要分離定義和實例,這可能是一個優點。
x <- 5
f <- local({ x <- x; function() x })
f()
## [1] 5
x <- 10
f()
## [1] 5
3)我們也可以考慮完全分離從實例化的功能。這也可以通過再次調用e $ init()來隨時重新初始化。
e <- local({
init <- function() {
p <- parent.env(environment())
p$x <- x
}
run = function() x
environment()
})
x <- 5
e$init()
e$run()
## [1] 5
x <- 10
e$run()
## [1] 5
4)(3)可以使用各種面向對象的框架,如引用類,原或R 6中來實現。在原這將是這樣的:
library(proto)
p <- proto(init = function(.) .$x <- x, run = function(.) x)
x <- 5
p$init()
p$run()
## [1] 5
x <- 10
p$run()
## [1] 5
不需要'parent.env' - 'x < - x'可以很好地工作(雖然看起來很奇怪)。 –
我們需要將x注入到父環境中,而不僅僅是檢索它。 x < - x不會那樣做。 –
我已經完成了'f < - local({x = 5; function()x})'',這似乎工作。 – Frank
還是用body
另一種選擇:
f<-`body<-`(function() {},value=x)
實施例:
x<-10
f<-`body<-`(function() {},value=x)
f()
#[1] 10
x<-100
f()
#[1] 10
挖的body
的源代碼,這裏是一個更好的解決方法相當於上面使用的as.function
:
f<-as.function(list(x))
用一行代碼:'f < - (function(){z <-x; function()return(z)})()'。 – nicola
「變量不被評估,除非它們的值被實際請求」 - 這是錯誤的。承諾(包括函數參數)是唯一的。 –
啊,的確如此。我誤解了。 –