Scala Language
Интерполяция строк
Поиск…
замечания
Эта функция существует в Scala 2.10.0 и выше.
Интерпретация Hello String
Интерполятор s позволяет использовать переменные в строке.
val name = "Brian"
println(s"Hello $name")
печатает «Hello Brian» на консоль при запуске.
Форматированная интерполяция строк с помощью интерполятора f
val num = 42d
Распечатайте два десятичных знака для num используя f
println(f"$num%2.2f")
42.00
Печать num использованием научной нотации с помощью электронной
println(f"$num%e")
4.200000e+01
Печать num в шестнадцатеричном с
println(f"$num%a")
0x1.5p5
Другие строки формата можно найти на странице https://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#detail
Использование выражения в строковых литералах
Вы можете использовать фигурные скобки для интерполяции выражений в строковые литералы:
def f(x: String) = x + x
val a = "A"
s"${a}" // "A"
s"${f(a)}" // "AA"
Без фигурных скобок scala будет только интерполировать идентификатор после $ (в этом случае f ). Поскольку нет никакого неявного преобразования из f в String это исключение в этом примере:
s"$f(a)" // compile-time error (missing argument list for method f)
Пользовательские строковые интерполяторы
В дополнение к встроенным можно определить пользовательские строковые интерполяторы.
my"foo${bar}baz"
Распространяется компилятором на:
new scala.StringContext("foo", "baz").my(bar)
scala.StringContext не имеет my метода, поэтому он может быть обеспечен неявным преобразованием. Обычай Интерполятор с таким же поведением , как и встроенный s интерпол затем будет осуществляться следующим образом :
implicit class MyInterpolator(sc: StringContext) {
def my(subs: Any*): String = {
val pit = sc.parts.iterator
val sit = subs.iterator
// Note parts.length == subs.length + 1
val sb = new java.lang.StringBuilder(pit.next())
while(sit.hasNext) {
sb.append(sit.next().toString)
sb.append(pit.next())
}
sb.toString
}
}
И интерполяция my"foo${bar}baz" будет обессоливать:
new MyInterpolation(new StringContext("foo", "baz")).my(bar)
Обратите внимание, что нет никаких ограничений на аргументы или возвращаемый тип функции интерполяции. Это приводит нас к темному пути, где синтаксис интерполяции может быть использован творчески для создания произвольных объектов, как показано в следующем примере:
case class Let(name: Char, value: Int)
implicit class LetInterpolator(sc: StringContext) {
def let(value: Int): Let = Let(sc.parts(0).charAt(0), value)
}
let"a=${4}" // Let(a, 4)
let"b=${"foo"}" // error: type mismatch
let"c=" // error: not enough arguments for method let: (value: Int)Let
Строковые интерполяторы как экстракторы
Также возможно использовать функцию интерполяции строк Scala для создания сложных экстракторов (шаблонов шаблонов), которые, возможно, наиболее широко используются в API квазикодов макросов Scala.
Учитывая, что n"p0${i0}p1" desugars для new StringContext("p0", "p1").n(i0) , возможно, неудивительно, что функция экстрактора включена, обеспечивая неявное преобразование из StringContext в класс с свойство n типа, определяющего метод unapply или unapplySeq .
В качестве примера рассмотрим следующий экстрактор, который извлекает сегменты пути, создавая регулярное выражение из частей StringContext . Затем мы можем делегировать большую часть тяжелого подъема методу unapplySeq предоставленному результатом scala.util.matching.Regex :
implicit class PathExtractor(sc: StringContext) {
object path {
def unapplySeq(str: String): Option[Seq[String]] =
sc.parts.map(Regex.quote).mkString("^", "([^/]+)", "$").r.unapplySeq(str)
}
}
"/documentation/scala/1629/string-interpolation" match {
case path"/documentation/${topic}/${id}/${_}" => println(s"$topic, $id")
case _ => ???
}
Обратите внимание, что объект path также может определить метод apply , чтобы вести себя как обычный интерполятор.
Интерполяция сырой строки
Вы можете использовать необработанный интерполятор, если вы хотите, чтобы строка была напечатана как есть и без какого-либо выхода из литералов.
println(raw"Hello World In English And French\nEnglish:\tHello World\nFrench:\t\tBonjour Le Monde")
С использованием исходного интерполятора вы должны увидеть следующее, напечатанное на консоли:
Hello World In English And French\nEnglish:\tHello World\nFrench:\t\tBonjour Le Monde
Без необработанного интерполятора \n и \t были бы экранированы.
println("Hello World In English And French\nEnglish:\tHello World\nFrench:\t\tBonjour Le Monde")
Печать:
Hello World In English And French
English: Hello World
French: Bonjour Le Monde