2012-02-02 6 views
2

別のスコープで使用されるvalを初期化するにはどうすればよいですか?以下の例では、if (iteration == 5){}スコープで初期化され、if (iteration > 5){}スコープで使用されるため、myOptimizedListをvarとして強制しています。 別のスコープで使用されるvalの初期化

val myList:A = List(...) 
var myOptimizedList:A = null 

for (iteration <- 1 to 100) { 
    if (iteration < 5) { 
     process(myList) 
    } else if (iteration == 5) 
     myOptimizedList = optimize(myList) 
    } 
    if (iteration > 5) { 
     process(myOptimizedList) 
    } 
} 

この

beforeを依頼されているかもしれませんが、[A]オプションを使用していますエレガントな解決策があるのだろうか。

答えて

8

あなたはコンテキストのうち、このコード例をとっているので、このソリューションは、あなたの本当のコンテキストのために非常に適していないことができますが、あなたはそれを簡単にするためにfoldLeftを使用できるようだ:

val myOptimizedList = (1 to 100).foldLeft (myList) { 
    case (list, 5) => optimize(list) 
    case (list, _) => process(list); list 
} 
2

多くの場合、問題を回避するためにコードを修正することができます。ここでは、単純な、と共通、例を考えてみましょう:

var x = 0 
if(something) 
    x = 5 
else 
    x = 6 
println(x) 

これは、ほとんどの言語ではかなり一般的なパターンになるが、Scalaはそれを行うためのより良い方法があります。具体的には、if文は、値を返すことができますので、より良い方法は次のとおりです。

val x = 
    if(something) 
    5 
    else 
    6 
println(x) 

だから我々は、すべての後にxのvalを作ることができます。

今、明らかにあなたのコードは、すべてのval Sを使用するように書き換えることができます。

val myList:A = List(...) 
for (iteration <- 1 to 5) 
    process(myList) 
val myOptimizedList = optimize(myList) 
for (iteration <- 5 to 100) 
    process(myOptimizedList) 

しかし、私は、これは単に例ではなく、あなたの本当の場合であると思います。しかし、あなたが実際のコードをどのように再配置して同様のことを実現するかがわからない場合は、それがどのように見えるかを教えてください。

3

することができますほとんど常に(尾)再帰関数として構築ループのいくつかの並べ替え書き換える:ここ

@annotation.tailrec def processLists(xs: List[A], start: Int, stop: Int) { 
    val next = start + 1 
    if (start < 5) { process(xs); processLists(xs, next, stop) 
    else if (start == 5) { processLists(optimize(xs), next, stop) } 
    else if (start <= stop) { process(xs); processLists(xs, next, stop) } 
} 
processLists(myList, 100, 1) 

を、あなたは前方にあなたがそうでなければ変異しているだろう、そのデータを渡します。膨大な数のものを変異させる必要がある場合は、扱いにくくなりますが、1〜2回は突然変異を行うよりはっきりとしていることが多いです。

2

遅い値を使用する myOptimizedListの初期化を遅らせるための別の手法(この場合はおそらくトリック)があります。あなたの例は非常に具体的ですが、プリンシパルは依然として明白です。最初に参照されるまでvalの割り当てを遅らせます。

val  myList   = List(A(), A(), A()) 
lazy val myOptimizedList = optimize(myList) 

for (iteration <- 1 to 100) { 
    if (iteration < 5) 
    process(myList) 
    else if (iteration > 5) 
    process(myOptimizedList) 
} 

ケースiteration == 5は無視されます。

関連する問題