Образец, соответствующий строкам как Seq [Char]

В 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

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

Ответ 1

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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