2012-08-16 10 views
22

Zum Beispiel habe ich diesen Fall Klasse:Fallklassen mit optionalen Felder in Scala

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

Wenn ich diesen Fall-Klasse verwenden, ist es möglich, dass die Daten zu den Feldern im Inneren des Gehäuses Klasse liefern optional? Zum Beispiel mache ich das:

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

Vielen Dank!

+1

Mit Fallklassen müssen Sie nicht "neu" verwenden. Es ist normalerweise ausgelassen. – akauppi

Antwort

27

Wenn Sie nur den zweiten Parameter ohne eine Standardinformation verpassen möchten, empfehle ich Ihnen Verwenden Sie eine Option.

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

Nun könnte man Instanzen auf diese Weise erstellen:

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

Um es nutzbar zu machen, wie man es wollte, ich werde ein implizites hinzufügen:

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

Jetzt können Sie anrufen es diese Wege:

import Student._ 

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

Danke! Ich bevorzuge diesen Code. Es läuft gut. : D – jeypijeypi

+40

Nooooooooo! Verwenden Sie keine impliziten Konvertierungen in Ihrem Code und insbesondere nicht zwischen gängigen Typen wie String und Option. Wenn dies "einfacher" gemacht werden muss, fügen Sie eine Überladung zu der Apply-Methode von Student hinzu. –

28

Sie waren in der Nähe:

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

val student = Student(firstName = "Foo") 

Eine weitere Möglichkeit zum Teil Funktion angewendet wird:

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) 

und vollständig zu sein, können Sie einige Standardobjekt erstellen und dann einige Feld ändern:

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

Vielen Dank für den Vorschlag. : D – jeypijeypi

6

würde ich sehe zwei Möglichkeiten, wie dies normalerweise gemacht wird.

1. Standardparameter

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

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

2. Alternative Konstrukteuren

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

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

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

welche besser hängt von den Umständen leicht ist. Letzteres gibt Ihnen mehr Freiheit: Sie können beliebige Parameter optional machen oder sogar ihre Reihenfolge ändern (nicht empfohlen). Standardparameter müssen immer am Ende der Parameterliste liegen, denke ich. Sie können diese beiden Möglichkeiten auch kombinieren.

Hinweis: Innerhalb der alternativen Konstruktoren benötigen Sie new, um den Compiler auf den eigentlichen Konstruktor zu verweisen. Normalerweise wird new nicht mit Fallklassen verwendet.

Verwandte Themen