2009-04-11 5 views
10

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

Примером этой функции упоминается в A Tour of 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] при любых обстоятельствах (включая включение шаблонов)? Однако без этого преобразования фрагмент кода не будет работать.

ответ

11

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

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

+0

Это имеет большой смысл и в основном то, что я догадывался. Однако я не нашел неявный конвертер. Спасибо, что указали это. Итак, в основном это основная уступка функциональности Java, жертвующая некоторой устойчивостью по типу. –

+2

Нет звука.Неявное преобразование - это просто компилятор, вставляющий вызов функции, что-то вроде val z: Seq [Char] = string2Seq (x) –

7

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

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

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

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

Scala cast выглядит так: x.asInstanceOf[Y].
То, что вы видите выше, присваивание: val z: Seq[Char] = x

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

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

+1

Концессия заключается в том, что String не может непосредственно наследовать от Seq [Char], поскольку это typedef для типа Java. –

+2

Извините, вы правы, что есть какая-то концессия (на самом деле scala плавает с ними) просто не то, что есть какая-то потеря устойчивости по типу, что означает что-то конкретное и здесь не затрагивается. – extempore

Смежные вопросы