1

以下の例を考えてみましょう。

> x=2
> myfun = function(y) x*y
> myfun(3)
[1] 6
> x=4
> myfun(3)
[1] 12

への参照ではなく、定義時のmyfun値をその定義が保持するように、どのように定義する必要がありますか? (つまり、2 番目の呼び出しでも 12 ではなく 6 が返されます)。xxmyfun(3)

編集: タイトルを変更して、不適切な用語を削除しました。

4

4 に答える 4

4

あなたの目的が何であるかを少し推測する必要があります。おそらく、引数の 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
于 2012-08-07T12:26:49.587 に答える
3

昨日、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
于 2012-08-07T13:04:38.067 に答える
2

別のクロージャーソリューションは次のとおりです。

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
于 2012-08-07T13:16:48.197 に答える
2

1 つのアプローチは次のとおりです。

myfun <- function(x = 2) {
    function(y) {
        x * y
    }
}

基本的に、必要な計算を行う関数を返す関数を作成します。上記のxはデフォルトで に設定さ2れていますが、 を呼び出すときにこれを変更できますmyfun。以下の例では、呼び出し時にmyfun()返された関数を保存します。foo

> foo <- myfun()

xこれで、グローバル環境で何をしても、その関数が呼び出されたときの環境で定義されたfoo()値が常に使用されます。xmyfun()

> foo(3)
[1] 6
> x <- 6
> foo(3)
[1] 6
> x <- 4
> foo(3)
[1] 6

関数の呼び出しによって作成された関数の環境には、関数が定義されたときに存在していた値がmyfun()含まxれているため、これはすべて機能します。xx

> environment(foo)$x
[1] 2
于 2012-08-07T13:06:10.513 に答える