كيف نفهم "معرف الحالة ~ اسم المستخدم => _" في anorm؟

StackOverflow https://stackoverflow.com/questions/9389757

  •  29-10-2019
  •  | 
  •  

سؤال

يحتوي anorm Play2 على DSL لطيف لمحلل النتائج:

case class User(id:Pk[String], name:String)

object User {
  val parser = get[String]("id") ~ get[String]("name") map { 
    case id ~ name => User(id,name) 
  }
}

أنا لا أفهم هذا الجزء case id ~ name, ، لماذا يمكن أن يكون هناك ~ بين متغيرين؟

أرى case عادة مثل:

case id => _
case (a,b) => _
case Array(a, _*) => _

لكنني لا أرى case id ~ name.

مصدر ~ هنا: https://github.com/playframework/Play20/blob/master/framework/src/anorm/src/main/scala/SqlParser.scala#L49

وهو يحدد فئة الحالة ~:

case class ~[+A, +B](_1:A, _2:B)

وأكتب اختبارًا بسيطًا:

case class ~[+A, +B](_1:A, _2:B)

new ~("a","b") match {
    case x ~ y => println(x , y)
}    

يطبع a,b, ولكن لماذا بناء الجملة case x ~ y?

هل كانت مفيدة؟

المحلول

أنت بالفعل في منتصف الطريق هناك.هذا ممكن لأن Scala يتيح لك القيام بذلك لجميع الأنواع التي تم الإعلان عنها اثنين معلمات النوع.

على سبيل المثال:

scala> case class Foo[X,Y]()
defined class Foo

scala> val x: Int Foo Double = Foo[Int,Double]()
x: Foo[Int,Double] = Foo()

على الرغم من أن الأمر قد يبدو غريبًا في البداية، إلا أنه في الواقع خاصية رائعة لأن بناء الجملة هذا يمكن أن يجعل الأشياء أكثر قابلية للقراءة.خذ بعين الاعتبار المثال التالي حيث يتم تعريف نوع مخصص لمجموعة:

class |::|[A, B](val left: A, val right: B)

object |::| {
  def unapply[A, B](o: A |::| B) = Some((o.left, o.right))
}

هنا، A |::| B يستخدم كتدوين infix لـ |::|[A, B].من ناحية أخرى، سكالا أيضًا يسمح بتدوين infix لمطابقة النمط (بفضل incrop للتذكير)، كما في حالة المُنشئ في المثال التالي:

new |::|("Hello","World") match {
  case l |::| r => Console println (l + "," + r)
  case _ =>
}  
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top