Pergunta

Eu tenho um método com muitos parâmetros implícitos:

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

Agora considere tal 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
     }
  }
}

Você pode ver esta linha no exemplo acima:

implicit val _user = user

Ele existe apenas para tornar o objeto user como um objeto implícito.Caso contrário, tenho que ligar hello como:

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

Estou pensando se existe alguma maneira de melhorar o código, por ex.não precisamos definir isso _user variável, mas faça o user está implícito.

Foi útil?

Solução

Sim, existe uma maneira de eliminar _user variável ao fazer user implícito:

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

ATUALIZAR: Respondendo à sua pergunta sobre muitos casos nos comentários abaixo.

Tudo depende do tipo de valor retornado por User.findById.Se é Option[User] mas você deseja corresponder usuários específicos (assumindo User é uma classe de caso), então a solução original ainda 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

Ou você pode combinar com qualquer outra coisa se quiser, contanto que User.findById é String => Option[User]

Se, por outro lado, User.findById é String => User então você pode simplesmente definir um objeto auxiliar como:

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

E use-o da seguinte maneira (novamente assumindo User é uma classe 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
    }
  }
}

ou combinando algum outro valor, digamos um 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 isso cubra todos os cenários que você possa ter.

Outras dicas

Não conheço nenhum truque como o caso Some(implicit user) mas e quanto

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top