パターンの一致に暗黙のうちに
-
10-12-2019 - |
質問
私は多くの暗黙的なパラメータを持つ方法を持っています:
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.findById
がString => Option[User]
の場合は、必要な場合に他のものに合わせることができます。
他方、User.findById
がString => 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
}
}
}
または他の値の一致、a 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)
.