2012-03-09 281 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