2010-08-31 9 views

Respuesta

13

El código repetitivo generado para las clases de casos tiene un costo pequeño pero no nulo en bytecode. Además del método copy, hay hashCode, equals y toString, así como el método de fábrica del objeto complementario.

Más significativo es el hecho de que no es aconsejable derivar clases de las clases de casos. Derivar una clase de caso de una clase de caso realmente invita a problemas (y el compilador le gritará). En particular, el compilador no genera ningún método anómalo copy(...), por lo que puede obtener algunos modos de falla impares si intenta copiar una clase de caso derivada de una clase de caso.

Si mantiene sus clases de casos en las hojas de cualquier gráfico de herencia, estará bien.

11

Usted recibirá properites para cualquier parámetros definidos y que será Vals (es decir, finales)

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)) 

Usted puede obtener este comportamiento con (es decir, las clases no casos) regulares, así:

// 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" 

Las clases de casos también traen muchas otras cosas, como implementaciones útiles de igualdad, hashcode y toString y un objeto complementario con un método de fábrica que elimina la necesidad de usar nuevas entre otras cosas.

Como puede ver, no se requiere una clase de caso para lograr lo que desea, pero lo lleva rápidamente. En cuanto a los efectos secundarios, la definición de una clase de caso genera un poco de código detrás de las escenas para proporcionarle lo que se describió en el párrafo anterior. A menudo son útiles y no me preocupo por ellos, pero es bueno saber sobre ellos.

+1

Gracias. Pero, ¿hay algún efecto secundario que pueda causar un comportamiento inesperado (lo que conduce a errores)? ¿Por qué uno usaría clases que no sean de casos en los casos habituales? – Ivan

7

Adicional a los puntos ya mencionados, una clase de caso es conceptualmente cercana a lo que se llamaría una "clase de valor" en Java. Por supuesto, nada le impide escribir clases de casos mutables o clases de casos con gran funcionalidad pero pocos datos, pero esto podría sorprender a otros que trabajan con su código. Como regla general yo diría que al menos lo piensen dos veces antes de crear clases de casos ...

  • que necesitan estado mutable
  • cuando no está seguro de si es posible que necesite más tarde subclases
  • si su principal objetivo es calcular las cosas (no para representar las cosas), y estos cálculos son complicados
  • si necesita un control más fino sobre su comportamiento (por ejemplo, necesita la coincidencia de patrones personalizados)
  • cuando el rendimiento es realmente importante
  • cuando solo necesita una de las "funciones de clase de caso", p. Consideraría usar una clase de caso simplemente para evitar escribir "val" delante de argumentos constructor como overkill
+0

¿Podría explicar por qué para evitar las clases de casos cuando el rendimiento es realmente importante? – ziggystar

+0

1) Las clases de casos necesitan hacer un poco más de trabajo en la construcción. 2) Las implementaciones para ##, equals, toString, etc. deben ser bastante elaboradas para evitar problemas en casos "vanguardistas", por lo que probablemente pueda guardar algunas operaciones implementándolas usted mismo. Tenga en cuenta que estoy hablando de diferencias de rendimiento mínimas que pueden importar para cosas como vectores y matrices para gráficos 3D, pero no para aplicaciones "normales". – Landei

4

Las otras respuestas están bien, pero el único riesgo real que extrañan es que las clases de caso tienen igualdad de valor, que se comporta de forma muy diferente a la igualdad de identidad orientada a objetos estándar. Dos objetos de caso son iguales si todos sus campos son iguales.Esto es exactamente lo que se necesita en algunos casos, pero muy inesperado en otros. En particular, agregar estado variable a algo con igualdad de valor es buscar problemas. Podrías encontrarte fácilmente con objetos cuyo código hash cambia con el tiempo, lo que da como resultado HashMaps corruptos y otras tales maldades.

Declarar algo así como una clase de caso para guardar unas pocas teclas y declarar sus propiedades como "val" es una economía falsa, y algún día morderá.

Cuestiones relacionadas