Diferencia entre objeto de caso y objeto

226

¿Hay alguna diferencia entre objeto de caso y objeto en scala?

Wojciech Durczyński
fuente
3
Él tiene un punto: no es necesario tener un objeto de caso para poder coincidir con el patrón. Creo que esto no fue abordado en la pregunta anterior ...
axel22
3
Pensé que habría una diferencia en el comportamiento de coincidencia de patrones, pero tanto un objeto de caso como un objeto normal se comportan de la misma manera en un AFAIK de coincidencia de patrones. Es bastante difícil encontrar información sobre objetos de casos, así que espero que alguien nos ilumine.
Edad Mooij
44
No es necesario usarlo casepara tener una coincidencia de patrones, es solo azúcar. Implementarte a unapplyti mismo hace el trabajo.
Raphael
1
La respuesta aceptada simplemente no responde la pregunta, como se discutió en los comentarios al respecto. Demasiado tarde para marcar la diferencia, pero debe tenerse en cuenta.
itsbruce
No es demasiado tarde para editar la respuesta aceptada. La edición se revisará y, si corresponde, se aceptará.
C4stor

Respuestas:

111

Las clases de casos difieren de las clases regulares en que obtienen:

  1. soporte de coincidencia de patrones
  2. implementaciones predeterminadas de equalsyhashCode
  3. implementaciones predeterminadas de serialización
  4. una implementación predeterminada más bonita de toString, y
  5. la pequeña cantidad de funcionalidad que obtienen al heredar automáticamente scala.Product.

La coincidencia de patrones, igual y hashCode no importan mucho para los singletons (a menos que haga algo realmente degenerado), por lo que está obteniendo la serialización, un buen toStringmétodo y algunos métodos que probablemente nunca usará.

Dave Griffith
fuente
46
Los puntos 3 y 4 de esta respuesta son la diferencia correcta entre objetos de caso y objetos. Los puntos 1 y 2 no importan para los objetos singleton. Y los objetos singleton siempre son productos con aridad 0, por lo que el punto 5 tampoco importa.
Wojciech Durczyński
86
Esta publicación perpetúa el mito que objectes lo mismo que un singleton. No lo es. Más bien es exactamente lo que dice que es, un objeto, es decir, una declaración y una instanciación en uno. Esto se limita objecta una sola instancia si se define en el alcance del paquete, lo que efectivamente lo convierte en un singleton, pero solo si se define EN ESE ALCANCE. Si se define dentro de una clase, puede tener tantas instancias como la clase en sí (se crea una instancia perezosa, por lo que no es necesariamente 1-1). Y esos objetos internos pueden muy bien ser utilizados como claves hash, haciendo que el valor predeterminado equals / hashCode sea muy sensible.
nilskp
66
La pregunta es sobre case objectno clase, ¿por qué es esta la respuesta correcta?
Ixx
10
Esto no responde la pregunta. Esta respuesta trata de la diferencia entre case classy a class. La pregunta es sobre la diferencia entre case objecty object.
MK
66
@ C4stor La respuesta no dice eso, sin embargo. Un objeto no es una clase. Dado que las clases de casos hacen una gran cantidad de magia detrás de escena, dados los diversos casos extremos y las complicaciones de Scala, no hay razón simplemente para suponer que la única diferencia entre un objeto Scala estándar y un objeto de caso se explica por lo que sabemos sobre la diferencia entre clases estándar y clases de caso. Esta respuesta ni siquiera aborda la redacción de la pregunta.
itsbruce
137

Aquí hay una diferencia: los objetos de caso extienden el Serializablerasgo, por lo que pueden serializarse. Los objetos normales no pueden por defecto:

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
fuente
15
Creo que los objetos de los casos se pueden serializar es la mayor diferencia con los objetos normales, especialmente en la comunicación de red entre actores
爱国者
14
Sin extends Serializableembargo, agregar debería hacer el mismo truco.
nilskp
36
scala> object foo

objeto definido foo

scala> case object foocase

foocase objeto definido

Diferencia de serialización:

scala> foo.asInstanceOf[Serializable]

java.lang.ClassCastException: foo $ no se puede convertir a scala.Serializable
... 43 elided

scala> foocase.asInstanceOf[Serializable]

res1: Serializable = foocase

toString diferencia:

scala> foo

res2: foo.type = foo $ @ 7bf0bac8

scala> foocase

res3: foocase.type = foocase

Minnie
fuente
2

Los objetos de caso vienen implícitamente con implementaciones de métodos toString, equals y hashCode, pero los objetos simples no. los objetos de caso se pueden serializar mientras que los objetos simples no, lo que hace que los objetos de caso sean muy útiles como mensajes con Akka-Remote. Agregar la palabra clave case antes de la palabra clave object hace que el objeto sea serializable.

Prashant_Sharma
fuente
0

Es similar con case classy class, solo usamos en case objectlugar de case classcuando no hay ningún campo que represente información de estado adicional.

Wineway
fuente
0

Conocemos objetos y "clase de caso" antes. Pero "objeto de caso" es una mezcla de ambos, es decir, es un singleton similar a un objeto y con una gran cantidad de repeticiones como en una clase de caso. La única diferencia es que el repetitivo se realiza para un objeto en lugar de una clase.

los objetos de caso no vendrán con los siguientes:

Aplicar, no aplicar métodos. Aquí no hay métodos de copia ya que es un singleton No hay método para la comparación de igualdad estructural. Ningún constructor también.

jeevan kishore
fuente