2011-06-27 12 views
7

Scala CreatorのProgramming in Scalaの本を読んでいるので、Setの例を少し混乱させています。valとvarを使用する場合、scalaの可変で不変のセットが使用される

ここでは不変のセットです:

var jetSet = Set("Boeing", "Airbus") 
jetSet += "Lear" 
println(jetSet.contains("Cessna")) 

これのポイントは何ですか?

このセットは変更できませんが、変数jetSetは変更可能です。 1)+ =でセットに追加するたびに、新しいセットが作成されますか?だから、変数は新しいセットをメモリにポイントしますか?

2)そうでなければなりません: val jetSet = set("cow","sheep","duck")?なぜそれはvarでなければならないのですか?不変集合にvarを使用する理由はありますか?

答えて

16

不変のデータ構造(この場合Set)の利点は、それらが永続的であることです。たとえば:jetSet2が使用されている場所jetSet1変数への更新は、このケースでは(コードの他の部分の副作用を持っていないため、これらの設定オブジェクトの

var jetSet1 = Set("Boeing", "Airbus") 
val jetSet2 = jetSet1 // ... imagine jetSet2 is somewhere else in the program 
jetSet1 += "Lear" 
assert(!jetSet2.contains("Lear")) 

不変性は、それが簡単にプログラムについて推論することができます)。この例からは明らかではありませんが、変更可能な値を変更可能なvar参照に格納すると便利な場合があります。ほとんどの場合、varのスコープは限定されています(たとえば、関数のローカル)。

不変のデータ構造には、しばしば効率的な巧妙な実装があります。残念ながら、ScalaコレクションAPIはパフォーマンスに関して十分に文書化されていませんが、ほとんどの操作はおおよそO(ログN)時間になると予想します。たとえば、大きな不変のセットsが与えられた場合、追加の要素を持つ新しいセットs + xを効率的に構築できるはずです。もちろん、不変性によって、sも保持されていることが保証されます。フードの下では、ss+xは、共有コンポーネントを持つ何らかの種類のツリーデータ構造を使用して格納されます。

あなたの質問のタイトルは、valまたはvarの使用に関するアドバイスも探していることを示唆しています。経験則はvalを便利に使用できるようにすることです。 varが必要な場合は、変数のスコープを可能な限り制限してください。

+2

APIに直接は含まれていませんが、パフォーマンスは* [ドキュメント化されています](http://www.scala-lang.org/docu/files/collections-api/collections.html)です。 – Debilski

+0

ありがとうございます –

+1

多くの操作は、O(log n)のように期待していますが、対数の基数が効果的にO(1)操作になるほど高いことが指摘されます。実際には、Scalaの不変のデータ構造に対する操作は、それらの変更可能ないとこに対する対応する操作の一定の要素の中にあります。 –

6

varを使用すると、変数をJavaに標準の変数宣言と見なすことができます。しかし、上記の場合、同じ変数に再割り当てしても、不変の変数を使用しているため、常に異なるセットになります。

例のポイントは、不変のコレクションを "変更"しようとしても、元のコレクションに触れずに新しいコレクションを作成することを示していました。作者がval(Javaでfinalの行に沿って)を使用した場合、新しい不変集合を保持するためにスコープ内に変数を導入する必要があります。私はおそらくvarが例を単純にするために使われたと思います。

0

valを使用すると、+=を実行できません。 val/var/defがシンボルに適用され、その値/実装には適用されません。 try val ... errorというコンパイルが表示されます。

+2

-1 'val = x:mutable.Set'に' + = 'をつけることができます。 –

関連する問題