在模式匹配中隐含

Fre*_*ind 7 scala implicit pattern-matching playframework-2.0

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

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

现在考虑这样一个类:

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
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

你可以在上面的例子中看到这一行:

implicit val _user = user
Run Code Online (Sandbox Code Playgroud)

它的存在只是为了使对象user成为一个隐式对象.否则,我必须打电话给hello:

hello("implicit")(a,b,c,... user)
Run Code Online (Sandbox Code Playgroud)

我在想是否有任何改进代码的方法,例如我们不需要定义那个_user变量但是user隐含它.

rom*_*usz 6

是的,有一种方法可以_useruser隐式时消除变量:

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

更新:在下面的评论中解决有关许多案例的问题.

这一切都取决于返回的值类型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
Run Code Online (Sandbox Code Playgroud)

或者,如果你愿意,你可以匹配任何其他东西,只要User.findByIdString => Option[User]

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

object withUser {
  def apply[A](user: User)(block: User => A) = block(user)
}
Run Code Online (Sandbox Code Playgroud)

并使用如下(再次假设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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

或者匹配其他一些价值,比如说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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望这涵盖了您可能拥有的所有场景.