2011-07-13 10 views
2

これはおそらくハーフベークされたアイデアですが、式の環境をコピーすることはできますか?次Scalaでクロージャをコピーすることはできますか?

6 
7 
8 
9 

しかし、私が本当にがしたいされています:私は次の出力を得る

class foo[T](block: => T) { 
    var data = {() => block } 
    def run() = { data() } 
} 

var a = 5 

var b = new foo({ a += 1; println(a) }) 
var c = new foo({ a += 1; println(a) }) 

b.run() 
c.run() 
b.run() 
c.run() 

次の例を考えてみましょう要するに

6 
6 
7 
7 

、私はしfooをしたいですブロックを参照するのではなく、初期値が解決された時点で、変数をブロック内にコピーします。これはできますか? scala.util.DynamicVariableは有望そうですが、上記の例でどのように使用するかを理解するのは難しいです。

答えて

2

あなたの問題は、aから初期化された別の変数をクローズするのではなく、(プログラムが実行されるにつれてその値を変更する)ことです。あなたはより多くのこのような何かをしようとする場合があります:

class bar[T](block: (T) => T, a: T) { 
    var cur = a 
    def run() = { cur = block(cur); cur } 
} 

var a = 5 

var b = new bar((r: Int) => { val q = r + 1; println(q); q }, a) 
var c = new bar((r: Int) => { val q = r + 1; println(q); q }, a) 

b.run() 
c.run() 
b.run() 
c.run() 

出力:

6 
6 
7 
7 

しかし、それは実行時にあなたのコードとは異なり、これはa変数の値に影響を与えないことに注意してください。

6

コピーを作成する場合は、コピーを作成しないでください。

var c = new foo({ var aa = a + 1; println(aa) }) 

あなたは変数を参照し、既存の閉鎖を取り、その変数のコピーを指し閉鎖にそれを有効にする場合は、その後、私はそれは不可能です怖いです。

非常にまれな状況や非常に制御された方法を除いて、可変変数は使用しないでください。つまり、彼らの参考文献をじゃまにすることではありません。

+2

可変変数に対する警告は+1です。 –

0

1)n.m。すでに述べたように、クロージャを使用するときは不変の概念を優先するべきです。

2)一方、これはまさにクロージャーのためのものです。彼らはの値をキャプチャしません、それらは変数それ自身をキャプチャします!あなたの質問はちょっと逆さまです。あなたは実際に環境をキャプチャしています - 変数の環境。 n.mと同じ変数をコピーする必要がない場合。またはIan McLairdがそれぞれ提案した。

関連する問題