2012-03-09 158 views
7

我有一个方法,用有很多隐含参数的内隐:模式匹配

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是隐含的。

回答

5

是的,有消除_user变量同时使user含蓄的方式:

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

UPDATE:寻址您在下面的评论中提到了许多案例。

这一切都取决于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) 
} 

并以此为FO llows(再次假设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 
    } 
    } 
} 

我希望这涵盖了所有你可能的方案。

+0

+1,如果模式匹配“Option”,这是一个很好的解决方案。但是如果有很多案例呢? – Freewind 2012-03-10 03:38:05

+0

@Freewind。我已经更新了我的答案,涵盖了许多“案例”。 – romusz 2012-03-10 19:50:55

2

我知道没招的,如案例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) 
+0

谢谢。我认为'hello(message)(implicit ...)'应该是现有的,不能改变,否则我们不需要定义它,只需定义一个'hello(message,user) )on就够了。 – Freewind 2012-03-09 13:06:50