2010-01-22 10 views
25

Las clases de casos en Scala son clases estándar mejoradas con coincidencia de patrones, iguales, ... (¿o estoy equivocado?). Además, no requieren una palabra clave "nueva" para su instanciación. Me parece que son más fáciles de definir que las clases regulares (¿o estoy otra vez equivocado?).¿Dónde las clases de casos NO se deben utilizar en Scala?

Hay muchas páginas web que indican dónde deben usarse (principalmente sobre la coincidencia de patrones). Pero, ¿dónde deberían evitarse? ¿Por qué no los usamos en todas partes?

Respuesta

20

Hay muchos lugares donde las clases de casos no son adecuados:

  • Cuando se desea ocultar la estructura de datos.
  • Como parte de una jerarquía de tipos de más de dos o tres niveles.
  • Cuando el constructor requiere consideraciones especiales.
  • Cuando el extractor requiere consideraciones especiales.
  • Cuando la igualdad y el código hash requieren consideraciones especiales.

A veces estos requisitos aparecen tarde en el diseño, y requiere uno para convertir una clase de caso en una clase normal. Dado que los beneficios de una clase de caso realmente no son tan buenos, aparte de los pocos casos especiales para los que fueron especialmente diseñados, mi propia recomendación es y no para convertir cualquier clase en caso, a menos que haya un uso claro para ello.

O, en otras palabras, no sobrediseñar.

16

Heredar de las clases de casos es problemático. Suponga que tiene código de este modo:

case class Person(name: String) { } 

case class Homeowner(address: String,override val name: String) 
    extends Person(name) { } 

scala> Person("John") == Homeowner("1 Main St","John") 
res0: Boolean = true 

scala> Homeowner("1 Main St","John") == Person("John") 
res1: Boolean = false 

Tal vez esto es lo que quieres, pero por lo general desea a == b si y sólo si b == a. Desafortunadamente, el compilador no puede solucionarlo de manera sensata automáticamente.

Esto se agrava debido a que el código hash de Person("John") no es el mismo que el código hash de Homeowner("1 Main St","John"), por lo que ahora es igual actúa raro y hashCode actúa raro.

Siempre que sepa qué esperar, heredar de las clases de casos puede dar resultados comprensibles, pero se ha visto como una mala forma (y, por lo tanto, ha quedado obsoleta en 2.8).

+0

¿Tiene un enlace a la función obsoleta que menciona, por favor? –

+2

Buscar "herencia de clase de caso en desuso" en Google y los tres primeros éxitos lo discutirán. La degradación ya está en la base de código 2.8; si descargas una compilación nocturna, puedes probarla con un ejemplo trivial. –

0

Puede ser tentador utilizar clases de casos porque quiere libre a String/equals/hashCode. Esto puede causar problemas, así que evita hacer eso.

Ojalá hubiera una anotación que te permitiera obtener esas cosas prácticas sin hacer una clase de caso, pero quizás eso sea más difícil de lo que parece.

+2

"puede causar problemas". ¿Qué problemas? –

1

Una desventaja que se menciona en Programming in Scala es que debido a las cosas generadas automáticamente para las clases de casos los objetos son más grandes que para las clases normales, por lo que si la eficiencia de la memoria es importante, puede usar clases regulares.

Cuestiones relacionadas