Differenza tra oggetto case e oggetto


226

C'è qualche differenza tra oggetto case e oggetto in scala?


3
Ha un punto: non è necessario disporre di un oggetto case per essere in grado di eseguire il pattern match su di esso. Penso che questo non sia stato affrontato nella domanda precedente ...
axel22

3
Ho pensato che ci sarebbe stata una differenza nel comportamento del pattern matching ma sia un case case che un oggetto normale si comportano allo stesso modo in un pattern match AFAIK. È abbastanza difficile trovare qualsiasi informazione sugli oggetti del caso, quindi non vedo l'ora che qualcuno ci illumini.
Età Mooij

4
Non è necessario utilizzare caseper avere una corrispondenza del modello, è solo zucchero. L'implementazione di unapplyte stesso fa il lavoro.
Raffaello

1
La risposta accettata non risponde alla domanda, come discusso nei commenti su di essa. Troppo tardi per fare la differenza, ma va notato.
itsbruce

Non è troppo tardi per modificare la risposta accettata. La modifica sarà rivista e, se pertinente, accettata.
C4stor,

Risposte:


111

Le classi di casi differiscono dalle classi normali in quanto ottengono:

  1. supporto di corrispondenza del modello
  2. implementazioni predefinite di equalsehashCode
  3. implementazioni predefinite di serializzazione
  4. un'implementazione predefinita più carina di toString, e
  5. la piccola quantità di funzionalità che ottengono ereditando automaticamente scala.Product.

Pattern matching, equals e hashCode non contano molto per i singoli (a meno che tu non faccia qualcosa di veramente degenerato), quindi stai praticamente ottenendo solo la serializzazione, un toStringmetodo carino e alcuni metodi che probabilmente non utilizzerai mai.


46
I punti 3 e 4 di questa risposta rappresentano la differenza corretta tra oggetti caso e oggetti. I punti 1 e 2 non contano per gli oggetti singleton. E gli oggetti singleton sono sempre prodotti con arity 0 quindi anche il punto 5 non ha importanza.
Wojciech Durczyński,

86
Questo post perpetua il mito che objectè lo stesso di un singleton. Non è. Piuttosto è esattamente quello che dice che è, un oggetto, cioè una dichiarazione e un'istanza in uno. Ciò si limita objecta una singola istanza se definita nell'ambito del pacchetto, il che la rende effettivamente un singleton, ma solo se definita IN QUESTO AMBITO. Se definito all'interno di una classe, puoi avere tante istanze quante la classe stessa (è pigramente istanziata, quindi non è necessariamente 1-1). E quegli oggetti interni possono benissimo essere usati come chiavi hash, rendendo sensibilmente predefiniti equals / hashCode.
nilskp,

66
La domanda case objectnon riguarda la classe, perché questa è la risposta corretta?
Ixx,

10
Questo non risponde alla domanda. Questa risposta si occupa della differenza tra case classe a class. La domanda riguarda la differenza tra case objecte object.
MK,

6
@ C4stor La risposta non lo dice però. Un oggetto non è una classe. Dato che le classi di casi fanno una buona dose di magia dietro le quinte, dati i vari casi e complicazioni di Scala, non c'è ragione di presumere che l'unica differenza tra un oggetto Scala standard e un oggetto caso sia spiegata da ciò che sappiamo della differenza tra classi standard e classi di casi. Questa risposta non affronta nemmeno la formulazione della domanda.
itsbruce

137

Ecco una differenza: gli oggetti case estendono il Serializabletratto, quindi possono essere serializzati. Gli oggetti regolari non possono essere predefiniti:

scala> object A
defined module A

scala> case object B
defined module B

scala> import java.io._
import java.io._    

scala> val bos = new ByteArrayOutputStream                                            
bos: java.io.ByteArrayOutputStream =  

scala> val oos = new ObjectOutputStream(bos)                                          
oos: java.io.ObjectOutputStream = java.io.ObjectOutputStream@e7da60                   

scala> oos.writeObject(B)

scala> oos.writeObject(A)
java.io.NotSerializableException: A$

15
Penso che gli oggetti caso possano essere serializzati sia la differenza più grande rispetto agli oggetti normali, specialmente nella comunicazione di rete tra attori
爱国者

14
L'aggiunta extends Serializabledovrebbe fare lo stesso trucco però.
nilskp,

36
scala> object foo

oggetto definito foo

scala> case object foocase

oggetto definito

Differenza di serializzazione:

scala> foo.asInstanceOf[Serializable]

java.lang.ClassCastException: foo $ non può essere lanciato su scala.Serializable
... 43 elided

scala> foocase.asInstanceOf[Serializable]

res1: serializzabile = foocase

toString differenza:

scala> foo

res2: foo.type = foo $ @ 7bf0bac8

scala> foocase

res3: foocase.type = foocase


2

gli oggetti case implicitamente includono implementazioni di metodi toString, equals e hashCode, ma gli oggetti semplici no. gli oggetti case possono essere serializzati mentre gli oggetti semplici no, il che rende gli oggetti case molto utili come messaggi con Akka-Remote. L'aggiunta della parola chiave case prima della parola chiave object rende l'oggetto serializzabile.


0

E 'simile con case classe class, usiamo case objectinvece case classquando non c'è alcun campo che rappresentano le informazioni di stato supplementari.


0

Conosciamo prima oggetti e "case class". Ma "case object" è un mix di entrambi, cioè è un singleton simile a un oggetto e con un sacco di boilerplate come in una classe case. L'unica differenza è che il boilerplate viene eseguito per un oggetto anziché per una classe.

gli oggetti case non verranno forniti con quelli seguenti:

Metodi di applicazione, non applicazione. qui non ci sono metodi di copia poiché questo è un singleton. Nessun metodo per il confronto dell'uguaglianza strutturale. Nessun costruttore pure.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.