2010-08-31 10 views

risposta

13

Il codice di codice generato per le classi del caso presenta un piccolo ma non zero costo in bytecode. Oltre al metodo copy, sono presenti , equals e toString e il metodo di produzione dell'oggetto associato.

Più significativo è il fatto che è sconsigliabile derivare classi da classi di casi. La derivazione di una classe di case da una classe di casi invoglia davvero problemi (e il compilatore ti urlerà contro). In particolare, il metodo copy(...) non viene sovrascritto dal compilatore, pertanto è possibile ottenere alcune modalità di errore dispari se si tenta di copiare una classe di caso derivata da una classe di caso.

Se mantieni le tue classi di casi alle foglie di qualsiasi grafico di ereditarietà, starai bene.

11

Otterrete properites per eventuali parametri definiti e saranno vals (vale a dire, le finali)

case class User(name: String, group: String) 
val user = User("jsmith", "admins") 

// access both properties 
println("name: %s group: %s".format(user.name, user.group)) 

È possibile ottenere questo comportamento con regolari (vale a dire, le classi non di casi), così:

// creates two final public properties as well 
class User(val name: String, val group: String) 

// creates read/write public properties 
class User(var name: String, var group: String) 
val user = new User("jsmith", "admins") 
user.group = "guests" 

Le classi di casi portano anche molte altre cose, come le utili implementazioni di uguaglianza, hashcode e toString e un oggetto complementare con un metodo factory che elimina la necessità di utilizzare nuove tra le altre cose.

Come potete vedere, una classe di casi non è necessaria per ottenere ciò che volete ma vi arriva rapidamente. Per quanto riguarda gli effetti collaterali, la definizione di una classe di casi genera un po 'di codice dietro le quinte per darti quello che è stato descritto nel paragrafo precedente. Questi sono spesso utili e tendo a non preoccuparmene, ma è bene conoscerli.

+1

Grazie. Ma ci sono degli effetti collaterali che possono causare un comportamento inaspettato (portando quindi a bug)? Perché si dovrebbero usare classi non casuali nei soliti casi? – Ivan

7

In aggiunta ai punti già citati, una classe di casi è concettualmente vicina a quella che chiameremmo "classe di valore" in Java. Ovviamente nulla ti impedisce di scrivere case classes mutevoli o case classes con funzionalità pesanti ma pochi dati, ma questo potrebbe sorprendere altri utenti che lavorano con il tuo codice. Come regola generale direi almeno pensarci due volte prima di creare classi case ...

  • che hanno bisogno di stato mutevole
  • quando non si è sicuri se si potrebbe aver bisogno sottoclassi tardi
  • se il loro principale scopo è quello di calcolare le cose (non per rappresentare le cose), e questi calcoli sono complicati
  • se avete bisogno di controllo a grana fine sul loro comportamento (ad esempio, è necessario modello personalizzato di corrispondenza)
  • quando le prestazioni sono veramente importante
  • quando è necessaria solo una delle "funzionalità case class", ad es. Mi piacerebbe prendere in considerazione utilizzando una classe case solo per evitare di digitare "Val" di fronte args costruttore come eccessivo
+0

Potresti spiegare perché evitare le case class quando le prestazioni sono davvero importanti? – ziggystar

+0

1) Le classi di casi devono fare un po 'più di lavoro sulla costruzione. 2) Le implementazioni di ##, equals, toString, ecc. Devono essere abbastanza elaborate per evitare problemi in casi "spigolosi", quindi puoi probabilmente salvare alcune operazioni implementandole tu stesso. Nota che sto parlando di differenze di prestazioni minime che possono avere importanza per elementi come vettori e matrici per la grafica 3D, ma non per le applicazioni "normali". – Landei

4

Le altre risposte sono tutte belle, ma quello vero rischio che manca è quel caso le classi hanno la parità di valore, che si comporta in modo molto diverso dall'uguaglianza identitaria orientata agli oggetti standard. Due case case sono uguali se tutti i loro campi sono uguali.Questo è esattamente ciò che è necessario in alcuni casi, ma molto inaspettato negli altri. In particolare, l'aggiunta di uno stato mutabile a qualcosa con l'uguaglianza dei valori richiede problemi. Potresti facilmente ritrovarti con oggetti il ​​cui codice hash cambia nel tempo, con conseguente HashMaps corrotto e altre cattiverie.

Dichiarare una classe di caso per salvare alcune sequenze di tasti che dichiarano le proprietà come "val" è una falsa economia e un giorno ti morderà.

Problemi correlati