ضمنية داخل تطابق النمط
-
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
}
}
}
أو مطابقة على بعض القيمة الأخرى ، ويقول 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)