Поиск…


замечания

Эта функция существует в 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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow