Implizit im Mustervergleich
-
10-12-2019 - |
Frage
Ich habe eine Methode mit vielen impliziten Parametern:
def hello(message:String)(implicit a:A,b:B,c:C, ..., user: User) = {...}
Betrachten Sie nun eine solche Klasse:
object Users extends Controller {
implicit a: A = ...
implicit b: B = ...
...
def index(id:String) = Action {
User.findById(id) match {
case Some(user) => {
implicit val _user = user
hello("implicit")
}
case _ => BadRequest
}
}
}
Sie können diese Zeile im obigen Beispiel sehen:
implicit val _user = user
Es existiert nur, um das Objekt zu erschaffen user
als implizites Objekt.Ansonsten muss ich anrufen hello
als:
hello("implicit")(a,b,c,... user)
Ich denke, ob es eine Möglichkeit gibt, den Code zu verbessern, z.Das müssen wir nicht definieren _user
variabel, aber machen Sie das user
ist implizit.
Lösung
Ja, es gibt eine Möglichkeit, es zu beseitigen _user
variabel während der Herstellung user
implizit:
def index(id:String) = Action {
User.findById(id) map (implicit user => hello("implicit")) getOrElse BadRequest
}
AKTUALISIEREN: Beantworten Sie Ihre Frage zu vielen Fällen in den Kommentaren unten.
Es hängt alles davon ab, welcher Werttyp zurückgegeben wird User.findById
.Wenn es Option[User]
Sie möchten jedoch bestimmte Benutzer abgleichen (vorausgesetzt). User
eine Fallklasse ist), dann gilt weiterhin die ursprüngliche Lösung:
def index(id:String) = Action {
User.findById(id) map { implicit user =>
user match {
case User("bob") => hello("Bob")
case User("alice") => hello("Alice")
case User("john") => hello("John")
case _ => hello("Other user")
}
} getOrElse BadRequest
Wenn Sie möchten, können Sie auch mit etwas anderem übereinstimmen, solange User.findById
Ist String => Option[User]
Wenn hingegen User.findById
Ist String => User
Dann können Sie einfach ein Hilfsobjekt definieren wie:
object withUser {
def apply[A](user: User)(block: User => A) = block(user)
}
Und verwenden Sie es wie folgt (wieder vorausgesetzt User
ist eine Fallklasse):
def index(id: String) = Action {
withUser(User findById id) { implicit user =>
user match {
case User("bob") => hello("Bob")
case User("alice") => hello("Alice")
case User("john") => hello("John")
case _ => BadRequest
}
}
}
oder passend zu einem anderen Wert, sagen wir an Int
:
def index(id: String, level: Int) = Action {
withUser(User findById id) { implicit user =>
level match {
case 1 => hello("Number One")
case 2 => hello("Number Two")
case 3 => hello("Number Three")
case _ => BadRequest
}
}
}
Ich hoffe, dass dies alle Szenarien abdeckt, die Sie haben könnten.
Andere Tipps
Ich kenne keinen solchen Trick Some(implicit user)
aber was ist mit
def hello(message: String, user: User)(implicit a: A, ... z: Z) = ...
def hello(message: String)(implicit a: A, ... z: Z, user: User) = hello(message, user)
case Some(user) => hello("implicit", user)