2011-06-27 15 views
7

Sto leggendo il libro Programming in Scala del Creatore di Scala e sono un po 'confuso sull'esempio di Set.set mutabile e immutabile di scala quando usare val e var

Qui spetta Immutabile Set:

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

Qual è il punto di questo?

Il set è immutabile ma la variabile jetSet è mutabile. 1) Quindi ogni volta che aggiungo al set con + = crea un nuovo set? Quindi la variabile punta a un nuovo set in memoria?

2) Non dovrebbe essere: val jetSet = set("cow","sheep","duck")? Perché deve essere una var? C'è un motivo per usare var per un set immutabile?

risposta

16

Il vantaggio delle strutture di dati immutabili, in questo caso Set, è che sono persistenti. Per esempio:

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

immutabilità di questi oggetti Set rende più facile ragionare sul programma perché gli aggiornamenti alla variabile jetSet1 non hanno effetti collaterali in altre parti del codice (in questo caso, ovunque jetSet2 viene utilizzato). Sebbene non sia chiaro da questo esempio, ci sono occasioni in cui è conveniente memorizzare valori immutabili nei riferimenti modificabili var; più spesso, lo var avrà un ambito limitato (ad es. locale per una funzione).

Le strutture di dati immutabili spesso hanno implementazioni intelligenti che sono piuttosto efficienti. Sfortunatamente, l'API della raccolta Scala non è ben documentata per quanto riguarda le prestazioni, ma mi aspetto che la maggior parte delle operazioni siano approssimativamente O (log N). Ad esempio, dato un grande Set immutabile s, si dovrebbe essere in grado di costruire in modo efficiente s + x, un nuovo Set con un elemento extra. Ovviamente, l'immutabilità garantisce che anche s venga conservato. Sotto il cofano, s e s+x verranno archiviati utilizzando una sorta di struttura dati ad albero con componenti condivisi.

Il titolo della tua domanda suggerisce che stai cercando anche consigli sull'utilizzo di val o var. La regola generale è quella di utilizzare val ogni volta che è possibile. Se è necessario un var, provare a limitare il più possibile l'ambito della variabile.

+2

Non direttamente nell'API, ma le prestazioni * sono * [documentate] (http://www.scala-lang.org/docu/files/collections-api/collections.html). – Debilski

+0

Grazie per il collegamento –

+1

Molte operazioni sono, come previsto, O (log n), ma è importante sottolineare che la base del logaritmo è così alta da renderle effettivamente operazioni O (1). In pratica, le operazioni sulle immutabili strutture dati di Scala sono all'interno di un fattore costante delle corrispondenti operazioni sui loro cugini mutevoli. –

6

var consente di riassegnare a una variabile, pensarlo come una dichiarazione di variabile normale in Java. Ma nel caso precedente, anche se si sta riassegnando alla stessa variabile, è sempre un insieme diverso poiché si sta utilizzando un valore immutabile.

Il punto dell'esempio era mostrare che anche se si prova a "modificare" una collezione immutabile, le modifiche creano una nuova collezione invece di toccare quella originale. Se l'autore avesse usato uno val (lungo le linee di final in Java), avrebbe dovuto introdurre una variabile in ambito per contenere il nuovo set immutabile. Penso che var sia stato probabilmente usato per mantenere l'esempio semplice.

0

non è possibile eseguire += se si utilizza val. il val/var/def si applica al simbolo e non al suo valore/implementazione prova val ... riceverai una compilazione error.

+2

-1 Si può fare '+ =' a 'val x: mutable.Set'. –