Вопрос

У меня есть метод, имеющий множество неявных параметров:

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

Теперь рассмотрим такой класс:

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

Вы можете увидеть эту строку в приведенном выше примере:

implicit val _user = user

Он существует только для того, чтобы создать объект user как неявный объект.В противном случае мне придется позвонить hello как:

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

Я думаю, есть ли какой-нибудь способ улучшить код, напримернам не нужно это определять _user переменной , но сделать так, чтобы user является неявным.

Это было полезно?

Решение

Да, есть способ устранить _user переменная при создании user неявный:

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

ОБНОВЛЕНИЕ: Отвечая на ваш вопрос о многих случаях в комментариях ниже.

Все зависит от того, какой тип значения возвращается User.findById.Если это Option[User] но вы хотите соответствовать конкретным пользователям (предполагая User является классом case), то исходное решение по-прежнему применяется:

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

Или вы можете подобрать что-нибудь еще, если хотите, при условии, что User.findById является String => Option[User]

Если, с другой стороны,, User.findById является String => User затем вы можете просто определить вспомогательный объект типа:

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

И используйте его следующим образом (опять же, предполагая User является классом case):

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

или сопоставление с каким-либо другим значением, скажем, с 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
    }
  }
}

Я надеюсь, что это охватывает все возможные сценарии, которые у вас могут возникнуть.

Другие советы

Я не знаю такого трюка, как кейс Some(implicit user) но как насчет

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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top