以下の例を考えてみましょう。
> x=2
> myfun = function(y) x*y
> myfun(3)
[1] 6
> x=4
> myfun(3)
[1] 12
への参照ではなく、定義時のmyfun
値をその定義が保持するように、どのように定義する必要がありますか? (つまり、2 番目の呼び出しでも 12 ではなく 6 が返されます)。x
x
myfun(3)
編集: タイトルを変更して、不適切な用語を削除しました。
以下の例を考えてみましょう。
> x=2
> myfun = function(y) x*y
> myfun(3)
[1] 6
> x=4
> myfun(3)
[1] 12
への参照ではなく、定義時のmyfun
値をその定義が保持するように、どのように定義する必要がありますか? (つまり、2 番目の呼び出しでも 12 ではなく 6 が返されます)。x
x
myfun(3)
編集: タイトルを変更して、不適切な用語を削除しました。
あなたの目的が何であるかを少し推測する必要があります。おそらく、引数の 1 つをデフォルト値で定義するだけで済みます。
myfun <- function(y, x=2){
x * y
}
次に、それを使用します。
x <- 3
myfun(4)
[1] 8
myfun(x=4, 3)
[1] 12
myfun(x)
[1] 6
しかし、おそらくあなたは本当に閉鎖を説明しています。
オブジェクトは機能を持つデータです。クロージャは、データを持つ関数です。
--- ジョン・D・クック
ここに例があります。最初に、スナップショットを記憶するクロージャーを定義します。
newSnapshot <- function(x){
xx <- x
function(y) xx * y
}
次に、それを使用します。
x <- 10
myfun <- newSnapshot(x)
myfun(4)
[1] 40
x <- 4
myfun(5)
[1] 50
昨日、R-help メーリング リストでほぼ同じ質問がありました。それを行うためのさまざまな方法については、Nabble の説明を参照してください。
http://r.789695.n4.nabble.com/Force-evaluation-of-a-symbol-when-a-function-is-created-td4639350.html
そして、これを行う3つの方法があります(Rヘルプの議論から集められました):
x <- 2
f1 <- local({x.now <- x;function(y) x.now*y})
f2 <- evalq(function(y)a*y,env=list(a=x))
multiply_by_x <- function(x) {
force(x)
function(y) y*x
}
f3 <- multiply_by_x(x)
結果付き
> f1(3)
[1] 6
> f2(3)
[1] 6
> f3(3)
[1] 6
> x <- 4
> f1(3)
[1] 6
> f2(3)
[1] 6
> f3(3)
[1] 6
別のクロージャーソリューションは次のとおりです。
myfun <- local({
x <- 2
list(
f=function(y) {
x*y
},
set.x=function(newx) {
x <<- newx
},
get.x=function() {
x
}
)
})
次に、次のように使用できます。
> myfun$get.x()
[1] 2
> myfun$set.x(5)
> myfun$get.x()
[1] 5
> myfun$f(3)
[1] 15
1 つのアプローチは次のとおりです。
myfun <- function(x = 2) {
function(y) {
x * y
}
}
基本的に、必要な計算を行う関数を返す関数を作成します。上記のx
はデフォルトで に設定さ2
れていますが、 を呼び出すときにこれを変更できますmyfun
。以下の例では、呼び出し時にmyfun()
返された関数を保存します。foo
> foo <- myfun()
x
これで、グローバル環境で何をしても、その関数が呼び出されたときの環境で定義されたfoo()
値が常に使用されます。x
myfun()
> foo(3)
[1] 6
> x <- 6
> foo(3)
[1] 6
> x <- 4
> foo(3)
[1] 6
関数の呼び出しによって作成された関数の環境には、関数が定義されたときに存在していた値がmyfun()
含まx
れているため、これはすべて機能します。x
x
> environment(foo)$x
[1] 2