Образец, соответствующий строке как Seq [Char] - PullRequest
10 голосов
/ 11 апреля 2009

В Scala можно формулировать шаблоны на основе невидимых символов строки, обрабатывая ее как Seq [Char].

Пример этой функции упоминается в Тур по Scala

Здесь приведен пример кода:

object RegExpTest1 extends Application {
 def containsScala(x: String): Boolean = {
   val z: Seq[Char] = x
   z match {
      case Seq('s','c','a','l','a', rest @ _*) =>
                println("rest is "+rest)
                true
      case Seq(_*) =>
                false
   }
 }

}

Проблема, с которой я столкнулся, - это третья строка фрагмента:

val z: Seq[Char] = x

Почему этот тип актерского состава необходим? Разве строка не должна вести себя как Seq [Char] при любых обстоятельствах (что может включать сопоставление с образцом)? Однако без этого преобразования фрагмент кода работать не будет.

Ответы [ 3 ]

18 голосов
/ 12 апреля 2009

В вопросе и комментариях происходит некоторое злоупотребление терминологией. В этом коде нет приведений, и, в частности, «Так что, по сути, это серьезная уступка совместимости с Java, приносящая в жертву некоторую устойчивость типов», в действительности не имеет оснований.

Состав скалы выглядит следующим образом: x.asInstanceOf[Y].
То, что вы видите выше, является заданием: val z: Seq[Char] = x

Это присваивание допустимо, поскольку существует неявное преобразование из String в Seq[Char]. Еще раз подчеркиваю: это не актерский состав . Приведение - это произвольное утверждение, которое может потерпеть неудачу во время выполнения. Невозможно неявное преобразование потерпеть неудачу.

Проблема зависимости от неявных преобразований между типами и ответа на исходный вопрос заключается в том, что неявные преобразования имеют место, только если исходное значение не проверяет тип. Поскольку сопоставление со строкой абсолютно законно, преобразование не выполняется, совпадение просто не удается.

11 голосов
/ 11 апреля 2009

Не уверен на 100%, если это правильно, но моя интуиция говорит, что без этого явного приведения вы бы сопоставили паттерн с java.lang.String, а это не то, что вам нужно.

Явное приведение заставляет компилятор Scala использовать Predef.stringWrapper неявное преобразование; таким образом, поскольку RichString расширяется Seq[Char], вы можете выполнить сопоставление с образцом, как если бы строка была последовательностью символов.

7 голосов
/ 12 апреля 2009

Я собираюсь повторить все, что сказал Андри. Для совместимости строки Scala java.lang.String s. В Predef есть неявное преобразование из String в RichString, которое реализует Seq[Char].

Возможно, более хороший способ кодирования соответствия шаблону без необходимости использования промежуточного значения z для хранения Seq[Char]:

def containsScala(x: String): Boolean = {
  (x: Seq[Char]) match {
    ...
  }
}
...