2012-08-16 28 views
22

por ejemplo, que tienen esta clase de caso:clases de casos con campos opcionales en Scala

case class Student (firstName : String, lastName : String) 

Si utilizo esta clase caso, es posible que el suministro de datos a los campos dentro de la clase caso son opcionales? Por ejemplo, haré esto:

val student = new Student(firstName = "Foo") 

¡Gracias!

+1

Con las clases de casos, no necesita utilizar 'nuevo'. Normalmente se deja afuera. – akauppi

Respuesta

27

Si solo quiere perderse el segundo parámetro sin una información predeterminada, le sugiero que use un Option.

case class Student(firstName: String, lastName: Option[String] = None) 

Ahora es posible crear instancias de esta manera:

Student("Foo") 
Student("Foo", None)   // equal to the one above 
Student("Foo", Some("Bar"))  // neccesary to add a lastName 

para que sea utilizable como lo hubiera querido, voy a añadir una implícita:

object Student { 
    implicit def string2Option(s: String) = Some(s) 
} 

Ahora puedes llamar Esas formas:

import Student._ 

Student("Foo") 
Student("Foo", None) 
Student("Foo", Some("Bar")) 
Student("Foo", "Bar") 
+0

¡Gracias! Yo prefiero este código Funciona bien. : D – jeypijeypi

+40

¡Noooooooo! No use conversiones implícitas en su código, y especialmente no entre tipos comunes como Cadena y Opción. Si esto debe hacerse "más fácil", agregue una sobrecarga al método de aplicación del alumno. –

28

estaban cerca:

case class Student (firstName : String = "John", lastName : String = "Doe") 

val student = Student(firstName = "Foo") 

Otra posibilidad es la función de aplicar parcialmente:

case class Student (firstName : String, lastName : String) 

val someJohn = Student("John", _: String) 
//someJohn: String => Student = <function1> 

val johnDoe = someJohn("Doe") 
//johnDoe: Student = Student(John,Doe) 

Y para ser completa, se puede crear un objeto predeterminado y luego cambiar algún campo:

val johnDeere = johnDoe.copy(lastName="Deere") 
//johnDeer: Student = Student(John,Deere) 
+0

Gracias por la sugerencia. : D – jeypijeypi

6

Lo hubiese dicho ver dos formas en que esto normalmente se hace.

1. parámetros por defecto

case class Student (firstName : String, lastName : String = "") 

Student("jeypijeypi") # Student(jeypijeypi,) 

2. constructores alternativos

case class Student (firstName : String, lastName : String) 

object Student { 
    def apply(firstName: String) = new Student(firstName,"") 
} 

Student("jeypijeypi") # Student(jeypijeypi,) 

cuál es mejor depende ligeramente de las circunstancias. Este último le da más libertad: puede hacer que los parámetros sean opcionales, o incluso cambiar su orden (no recomendado). Los parámetros predeterminados siempre deben estar al final de la lista de parámetros, creo. También puedes combinar estas dos formas.

Nota: dentro de los constructores alternativos necesita new para apuntar el compilador al constructor real. Normalmente new no se usa con las clases de casos.

Cuestiones relacionadas