لماذا لا تتطابق السلسلة الفارغة كما seq.empty؟
-
09-09-2019 - |
سؤال
تحرير: كان هذا علة قديمة منذ فترة طويلة منذ إصلاحها في Scala 2.8 والإصدارات الأحدث
خلال بعض التجريب حول السؤال نمط مطابقة سلسلة كما SEQ [char, ركضت عبر ظاهرة أخرى مطابقة أخرى. النظر في التعليمات البرمجية التالية التي تعامل سلسلة كسلسلة من الأحرف:
def %%&#(input: String) : String = {
val uha : Seq[Char] = input
uha match {
case Seq() => "Empty"
case Seq(first @ _, 'o', 'o') => "Bar"
case _ => "Oh"
}
}
استدعاء المدخلات على السلسلة الفارغة ""
غلة بشكل صحيح "Empty"
.
ومع ذلك، إذا قمت بإعادة كتابة جملة المباراة الأولى
case Seq.empty => "Empty"
مطابقة ""
يفشل ويطابق البند الافتراضي بدلا من ذلك.
المشي من خلال شفرة المصدر مكتبة Scala (التي لا يجب عليك القيام بها في عالم مثالي :-)) أعتقد أن كلاهما Seq()
و Seq.empty
سوف يؤدي إلى RandomAccessSeq.empty
. وبعد على ما يبدو، هذا لا يتفق مع ظاهرة الموصوفة أعلاه بسبب فقط Seq()
يطابق السلسلة الفارغة.
تحديث: عند بعض التجريب الإضافي، يمكن تضييق هذا السؤال إلى ما يلي:
val list = List()
>>> list2: List[Nothing] = List()
val emptySeq = Seq.empty
list == emptySeq
>>> res1: Boolean = false
هذا يعني أساسا أن فارغة Seq
لا يساوي تلقائيا Seq.empty
وبعد لذلك عند مطابقة ضد ثابت (على عكس استخدام النازع كما اقترحه Starblue) يؤدي هذا عدم المساواة إلى المباراة الفاشلة. وينطبق الشيء نفسه عند تفسير الفارغة String
كتسلسل.
المحلول
يبدو أن هذا خطأ في المكتبة. هل ترغب في تقديم الخطأ أو يجب علي؟
scala> Seq.empty match {case Seq() => "yup"; case _ => "nope"}
res0: java.lang.String = yup
scala> Seq() match {case Seq.empty => "yup"; case _ => "nope"}
res1: java.lang.String = yup
scala> ("" : Seq[Char]) match {case Seq() => "yup"; case _ => "nope"}
res2: java.lang.String = yup
scala> ("" : Seq[Char]) match {case Seq.empty => "yup"; case _ => "nope"}
res3: java.lang.String = nope
نصائح أخرى
في مطابقة وظائف Unapply أو UnapplyseQ تستخدم، لا تنطبق كما يبدو أنك تصدق.