Unterschied zwischen Fallobjekt und Objekt

225

Gibt es einen Unterschied zwischen Fallobjekt und Objekt in Scala?

Wojciech Durczyński
quelle
3
Er hat einen Punkt - es ist nicht notwendig, ein Fallobjekt zu haben, um eine Musterübereinstimmung darauf zu haben. Ich denke, dies wurde in der vorherigen Frage nicht angesprochen ...
axel22
3
Ich dachte, es würde einen Unterschied im Mustervergleichsverhalten geben, aber sowohl ein Fallobjekt als auch ein normales Objekt verhalten sich in einem Mustervergleichs-AFAIK gleich. Es ist ziemlich schwierig, überhaupt Informationen über Fallobjekte zu finden, deshalb freue ich mich auf jemanden, der uns aufklärt.
Alter Mooij
4
Es ist nicht notwendig, caseMusterabgleich zu verwenden, es ist nur Zucker. unapplySich selbst zu implementieren macht den Job.
Raphael
1
Die akzeptierte Antwort beantwortet die Frage einfach nicht, wie in den Kommentaren dazu besprochen. Viel zu spät, um etwas zu bewirken, sollte aber beachtet werden.
Itsbruce
Es ist noch nicht zu spät, die akzeptierte Antwort zu bearbeiten. Die Bearbeitung wird überprüft und gegebenenfalls akzeptiert.
C4stor

Antworten:

110

Fallklassen unterscheiden sich von regulären Klassen darin, dass sie Folgendes erhalten:

  1. Mustervergleichsunterstützung
  2. Standardimplementierungen von equalsundhashCode
  3. Standardimplementierungen der Serialisierung
  4. eine schönere Standardimplementierung von toString, und
  5. die geringe Menge an Funktionen, die sie durch das automatische Erben von erhalten scala.Product.

Pattern Matching, Equals und HashCode spielen für Singletons keine große Rolle (es sei denn, Sie tun etwas wirklich Entartetes). Sie erhalten also so ziemlich nur Serialisierung, eine nette toStringund einige Methoden, die Sie wahrscheinlich nie verwenden werden.

Dave Griffith
quelle
46
Punkt 3 und 4 dieser Antwort sind korrekte Unterschiede zwischen Fallobjekten und Objekten. Punkt 1 und 2 spielen für Singleton-Objekte keine Rolle. Und Singleton-Objekte sind immer Produkte mit der Arität 0, sodass Punkt 5 ebenfalls keine Rolle spielt.
Wojciech Durczyński
86
Dieser Beitrag verewigt den Mythos, objectder mit einem Singleton identisch ist. Es ist nicht. Vielmehr ist es genau das, was es sagt, ein Objekt, dh eine Erklärung und Instanziierung in einem. Dies beschränkt sich objectauf eine einzelne Instanz, wenn sie im Paketbereich definiert ist, wodurch sie effektiv zu einem Singleton wird, jedoch nur, wenn sie in DIESEM GELTUNGSBEREICH definiert ist. Wenn innerhalb einer Klasse definiert, können Sie so viele Instanzen haben wie die Klasse selbst (sie wird träge instanziiert, ist also nicht unbedingt 1-1). Und diese inneren Objekte können sehr gut als Hash-Schlüssel verwendet werden, was den Standardwert equals / hashCode sehr sinnvoll macht.
Nilskp
66
Die Frage ist case objectnicht Klasse, warum ist das die richtige Antwort?
Ixx
10
Dies beantwortet die Frage nicht. Diese Antwort befasst sich mit dem Unterschied zwischen case classund a class. Die Frage ist über den Unterschied zwischen case objectund object.
MK
6
@ C4stor Die Antwort sagt das allerdings nicht. Ein Objekt ist keine Klasse. Angesichts der Tatsache, dass Fallklassen hinter den Kulissen ziemlich viel Magie bewirken, gibt es angesichts der verschiedenen Randfälle und Komplikationen von Scala keinen Grund anzunehmen, dass der einzige Unterschied zwischen einem Standard-Scala-Objekt und einem Fallobjekt durch das erklärt wird, was wir über den Unterschied wissen zwischen Standardklassen und Fallklassen. Diese Antwort spricht nicht einmal den Wortlaut der Frage an.
Itsbruce
137

Hier ist ein Unterschied: Fallobjekte erweitern das SerializableMerkmal, sodass sie serialisiert werden können. Normale Objekte können nicht standardmäßig:

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$
axel22
quelle
15
Ich denke, dass
Fallobjekte
14
Das Hinzufügen extends Serializablesollte jedoch den gleichen Trick ausführen.
Nilskp
36
scala> object foo

definiertes Objekt foo

scala> case object foocase

definierte Objekt-Foocase

Serialisierungsunterschied:

scala> foo.asInstanceOf[Serializable]

java.lang.ClassCastException: foo $ kann nicht in scala.Serializable
... 43 elided umgewandelt werden

scala> foocase.asInstanceOf[Serializable]

res1: Serialisierbar = Foocase

toString Unterschied:

scala> foo

res2: foo.type = foo $ @ 7bf0bac8

scala> foocase

res3: foocase.type = foocase

Minnie
quelle
2

case-Objekte werden implizit mit Implementierungen von Methoden toString, equals und hashCode geliefert, einfache Objekte jedoch nicht. Fallobjekte können serialisiert werden, während einfache Objekte dies nicht können, was Fallobjekte als Nachrichten mit Akka-Remote sehr nützlich macht. Durch Hinzufügen des Schlüsselworts case vor dem Schlüsselwort object wird das Objekt serialisierbar.

Prashant_Sharma
quelle
0

Es ist ähnlich wie mit case classund classverwenden wir nur case objectstatt , case classwenn es keine Felder , die zusätzliche Statusinformationen.

Weinweg
quelle
0

Wir kennen Objekte und "Fallklasse" vorher. Aber "case object" ist eine Mischung aus beidem, dh es ist ein Singleton ähnlich einem Objekt und mit viel Boilerplate wie in einer Case-Klasse. Der einzige Unterschied besteht darin, dass die Boilerplate für ein Objekt anstelle einer Klasse erstellt wird.

Fallobjekte werden nicht mit den folgenden geliefert:

Anwenden, Methoden nicht anwenden. Hier gibt es keine Kopiermethoden, da dies ein Singleton ist. Keine Methode zum Vergleich der strukturellen Gleichheit. Auch kein Konstruktor.

Jeevan Kishore
quelle