2016-07-11 12 views
3

Ich bin neu bei scala. Was bedeutet folgende Syntax?Scala: Konstruktor mit zwei Parethenhesen

case class User(val id: Long)(val username: String) 

Ich habe über currying in scala lesen, aber bitte erklären, wie es zu Bau oben im Zusammenhang (falls bezogen). Danke.

Antwort

1

Es ermöglicht Ihnen, das Objekt in Schritten zu erstellen.

val user = User(123L) _ // user now has only the ID 

// later on 
val completeUser = user("moreo") // user now also has the username 

Dies ist im Allgemeinen nützlich, wenn Sie Ihr Objekt folgen eine Schnittstelle haben wollen, müssen aber zusätzliche Parameter zu übergeben, so dass Sie zunächst mit den Parametern Ihr Objekt initialisieren und Sie erhalten dann später eine Funktion, die die Schnittstelle folgen .

+4

nicht genau - Ihre Antwort kompiliert nicht, Sie sollten 'User (123L) _' schreiben, um den partiell angewendeten Konstruktor zu erhalten. –

+0

Auch wichtig zu beachten, dass der Typ von 'user' hier _not_' User' ist, aber eine Funktion: 'String => User' – Dima

+0

Danke für die Antwort. Ich habe versucht, folgendes zu tun: Fallklasse Benutzer (Val-ID: Lang, implizite val-Repository: UserRepository), aber es hat Kompilierungsfehler, also, wenn ich in die Fallklasse geändert habe Benutzer (val id: Long) (implizite val Repository: UserRepository) - es funktioniert. Aber warum der erste Ansatz nicht funktioniert. Repository-Eigenschaft ist für die Klasse erforderlich, und wie Sie gesagt haben, wenn ich Benutzerklasse ohne zweiten Parameter initialisieren kann, wäre die Klasse inkonsistent. Wie kann ich dieses Problem lösen? – Teimuraz

5

Wie teilweise angewandte Funktionen, ein Konstruktor (die eine Funktion von seinen Argumenten für den konstruierten Typen ist), teilweise angewandt werden kann, in diesem Fall:

scala> case class User(val id: Long)(val username: String) 
defined class User 

scala> val userBuilder = User(123L) _ 
userBuilder: String => User = <function1> 

Hinweis des Typ des resultierenden userBuilder - es ist eine Funktion von String (die restlichen Parameter) zu User

nun wie Funktionen teilweise angewendet, können Sie dieses Ergebnis in einen String anwenden können und eine User Instanz erhalten:

scala> val user = userBuilder("a") 
user: User = User(123) 

scala> user.username 
res1: String = a 

Wann ist das nützlich?

  1. Wenn Sie viele Instanzen mit gemeinsamen Werten für eine Teilmenge der Argumente, zum Beispiel konstruieren wollen:

    case class Person(lastName: String)(val firstName: String) 
    
    class Family(lastName: String, firstNames: List[String]) { 
        def getMembers: List[Person] = { 
        val creator = Person(lastName) _ // will be reused for each first name! 
        firstNames.map(creator) 
        } 
    } 
    
  2. Wenn Sie verwenden möchten, ein Argument als Standardwert eines anderen:

    case class Measure(min: Int)(val max: Int = min*2) 
    
    Measure(5)() // max = 10 
    Measure(5)(12) // default overridden, max = 12 
    
  3. Wenn Sie implicit Argumente verwenden möchten, die muss in einem separat wohnen e, letzte Argumentliste der Funktion, wie int der Scala Language Specification (Kapitel 7.2) beschrieben:

Verfahren oder Konstrukteur kann nur eine implizite Parameterliste haben, und es muss die letzte Parameterliste sein, gegeben.

Verwandte Themen