Sto iniziando Scala. Ho ragione nel capire che dovrei definire una classe come una case case se mi piacerebbe che gli argomenti fossero esposti come proprietà? Non introduce effetti collaterali?È corretto definire tutte le classi come casi in Scala solo per avere tutti i loro argomenti creati automaticamente?
risposta
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.
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.
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
Potresti spiegare perché evitare le case class quando le prestazioni sono davvero importanti? – ziggystar
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
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à.
- 1. I casi d'uso per le classi finali
- 2. creati automaticamente le classi C# per XML deserializzazione non funzionano
- 3. Superinterface e superclasse XJC solo per tutte le classi?
- 4. Come chiamare i metodi sovrascritto in tutte le classi derivate
- 5. Come definire le classi dei casi con membri con parametri di tipo non associato?
- 6. Risoluzione dei conflitti: come accettare automaticamente le "loro" modifiche?
- 7. Casi d'uso per gli stream in Scala
- 8. Come definire le dipendenze di solo test?
- 9. È possibile definire più classi in un solo file .cpp?
- 10. Distribuzione singola per tutti i casi di test in Arquillian
- 11. Modo corretto per creare classi in JavaScript?
- 12. Qualsiasi modo per correggere automaticamente tutte le classi variabili in un dataframe
- 13. mostra tutte le immagini solo dopo il loro carico completo
- 14. Creare tratto comune per tutte le classi di casi di supporto copia (id = NEWID) Metodo
- 15. Come eseguire un metodo prima di tutti i test in tutte le classi?
- 16. È appropriato definire una classe di caso Scala non banale?
- 17. Elenca tutte le classi SENZA Javadoc
- 18. selezionare tutti i record creati nell'ora
- 19. Scala: le classi sono sufficienti?
- 20. Come aggiungere @ Override, @Deprecate e i modificatori statici ai metodi automaticamente per tutte le classi Java del progetto dove necessario?
- 21. Modo corretto per controllare tutte le checkbox in ListView?
- 22. Come posso estrarre tutte le classi in un file separato?
- 23. definire argomenti con nome predefinito in termini di altri argomenti in scala
- 24. Ottenere tutte le classi interne per riflessione
- 25. Come definire una funzione come generica su tutti i numeri in scala?
- 26. Come posso avere una variabile costante comune a tutte le classi in un pacchetto?
- 27. Scala: copia di classi di casi con tratto
- 28. git: elenca solo i file modificati per tutte le armature
- 29. Le funzioni freccia ES6 hanno i loro argomenti o no?
- 30. Ottieni tutte le classi che implementano un tratto in Scala utilizzando la riflessione
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