Pregunta

Tengo un método que tiene muchos parámetros implícitos:

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

Ahora considere una clase así:

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

Puede ver esta línea en el ejemplo anterior:

implicit val _user = user

Existe sólo para hacer el objeto. user como un objeto implícito.De lo contrario, tengo que llamar hello como:

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

Estoy pensando si hay alguna forma de mejorar el código, por ejemplo.no necesitamos definir eso _user variable pero hacer el user está implícito.

¿Fue útil?

Solución

Sí, hay una manera de eliminar. _user variable mientras se hace user implícito:

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

ACTUALIZAR: Respondiendo su pregunta sobre muchos casos en los comentarios a continuación.

Todo depende del tipo de valor que devuelva User.findById.Si es Option[User] pero desea hacer coincidir usuarios específicos (asumiendo User es una clase de caso), entonces la solución original aún se aplica:

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 puedes combinar cualquier otra cosa si quieres, siempre y cuando User.findById es String => Option[User]

Si, por el contrario, User.findById es String => User entonces simplemente puedes definir un objeto auxiliar como:

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

Y utilícelo de la siguiente manera (nuevamente asumiendo User es una clase de 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 hacer coincidir algún otro valor, digamos 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
    }
  }
}

Espero que esto cubra todos los escenarios que pueda tener.

Otros consejos

No conozco ningún truco como el caso Some(implicit user) pero que pasa

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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top