Implicito all'interno della partita del modello
-
10-12-2019 - |
Domanda
Ho un metodo, con un sacco di parametri impliciti:
def hello(message:String)(implicit a:A,b:B,c:C, ..., user: User) = {...}
.
Ora considera una tale classe:
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
}
}
}
.
Puoi vedere questa riga nel campione sopra:
implicit val _user = user
.
Esiste solo per rendere l'oggetto user
come un oggetto implicito.Altrimenti, devo chiamare hello
come:
hello("implicit")(a,b,c,... user)
.
Sto pensando se c'è un modo per migliorare il codice, ad es.Non abbiamo bisogno di definire quella variabile _user
ma rendere il user
è implicito.
Soluzione
Sì, c'è un modo per eliminare la variabile _user
durante la creazione di user
implicita:
def index(id:String) = Action {
User.findById(id) map (implicit user => hello("implicit")) getOrElse BadRequest
}
.
Aggiornamento: Affronta la tua domanda su molti casi nei commenti qui sotto.
Tutto dipende da quale tipo di valore viene restituito da User.findById
.Se è Option[User]
ma vuoi abbinare sugli utenti specifici (supponendo che User
sia una cassa di cassa), quindi la soluzione originale si applica ancora:
.
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
o puoi abbinare su qualsiasi altra cosa se vuoi, finché User.findById
è String => Option[User]
Se, d'altra parte, User.findById
è String => User
, quindi è sufficiente definire un oggetto helper come:
.
object withUser {
def apply[A](user: User)(block: User => A) = block(user)
}
e usalo come segue (di nuovo supponendo che User
sia una cassa del caso):
.
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
}
}
}
o corrispondenza su un altro valore, ad esempio un 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
}
}
}
Spero che questo copia tutti gli scenari che potresti avere.
Altri suggerimenti
Non conosco nessun trucco come caso Some(implicit user)
ma che dire
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)
.