Question

J'ai une méthode, avec beaucoup de paramètres implicites :

def hello(message:String)(implicit a:A,b:B,c:C, ..., user: User) = {...}

Considérons maintenant une telle 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
     }
  }
}

Vous pouvez voir cette ligne dans l'exemple ci-dessus :

implicit val _user = user

Il existe juste pour fabriquer l'objet user comme objet implicite.Sinon, je dois appeler hello comme:

hello("implicit")(a,b,c,... user)

Je me demande s'il existe un moyen d'améliorer le code, par ex.nous n'avons pas besoin de définir cela _user variable mais faire le user est implicite.

Était-ce utile?

La solution

Oui, il existe un moyen d'éliminer _user variable lors de la création user implicite:

def index(id:String) = Action {
  User.findById(id) map (implicit user => hello("implicit")) getOrElse BadRequest
}

MISE À JOUR: Répondant à votre question sur de nombreux cas dans les commentaires ci-dessous.

Tout dépend du type de valeur renvoyé par User.findById.Si c'est Option[User] mais vous souhaitez faire correspondre des utilisateurs spécifiques (en supposant User est une classe de cas), alors la solution originale s'applique toujours :

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

Ou vous pouvez faire correspondre n'importe quoi d'autre si vous le souhaitez, à condition que User.findById est String => Option[User]

Si, par contre, User.findById est String => User alors vous pouvez simplement définir un objet d'assistance comme :

object withUser {
  def apply[A](user: User)(block: User => A) = block(user)
}

Et utilisez-le comme suit (en supposant encore une fois User est une classe de cas) :

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
    }
  }
}

ou une correspondance sur une autre valeur, disons 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
    }
  }
}

J'espère que cela couvre tous les scénarios que vous pourriez avoir.

Autres conseils

Je ne connais aucune astuce comme celle-ci Some(implicit user) mais qu'en est-il

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top