Вопрос

Редактировать:Это была старая ошибка, давно исправленная в 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, как вы, кажется, полагаете.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top