我有一个方法,有很多隐式参数:

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 是一个案例类),那么原来的解决方案仍然适用:

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.findByIdString => Option[User]

另一方面,如果 User.findByIdString => User 那么你可以简单地定义一个辅助对象,例如:

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

并按如下方式使用它(再次假设 User 是一个案例类):

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

我希望这涵盖了您可能遇到的所有场景。

其他提示

我不知道有什么诡计,比如case 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