Почему пустая строка не совпадает с 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"
.
Однако, если я перепишу первое предложение match как
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, а не apply, как вы, кажется, полагаете.