Buscar..


Observaciones

Esta característica existe en Scala 2.10.0 y superior.

Hola Interpolación De Cuerdas

El interpolador s permite el uso de variables dentro de una cadena.

val name = "Brian"
println(s"Hello $name")

Imprime "Hola Brian" en la consola cuando se ejecuta.

Interpolación de cadena formateada utilizando el Interpolador f

val num = 42d

Imprime dos decimales para num utilizando f

println(f"$num%2.2f")
42.00

Imprimir num usando notación científica usando e

println(f"$num%e")
4.200000e+01

Imprimir num en hexadecimal con una

println(f"$num%a")
0x1.5p5

Otras cadenas de formato se pueden encontrar en https://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#detail

Usando la expresión en cadenas literales

Puede usar llaves para interpolar expresiones en literales de cadena:

def f(x: String) = x + x
val a = "A"

s"${a}"    // "A"
s"${f(a)}" // "AA"

Sin las llaves, Scala solo interpolaría el identificador después de $ (en este caso f ). Dado que no hay una conversión implícita de f en una String esta es una excepción en este ejemplo:

s"$f(a)"  // compile-time error (missing argument list for method f)

Interpoladores de cadena personalizados

Es posible definir interpoladores de cadena personalizados además de los integrados.

my"foo${bar}baz"

Es expandido por el compilador a:

new scala.StringContext("foo", "baz").my(bar)

scala.StringContext no tiene my método, por lo tanto, se puede proporcionar por conversión implícita. Un interpolador personalizado con el mismo comportamiento que la orden interna s interpolador entonces ser implementado de la siguiente manera:

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
  }
}

Y la interpolación de my"foo${bar}baz" se desugaría a:

new MyInterpolation(new StringContext("foo", "baz")).my(bar)

Tenga en cuenta que no hay restricción en los argumentos o el tipo de retorno de la función de interpolación. Esto nos lleva por un camino oscuro donde la sintaxis de interpolación se puede usar creativamente para construir objetos arbitrarios, como se ilustra en el siguiente ejemplo:

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

Interpoladores de cadenas como extractores.

También es posible utilizar la función de interpolación de cadenas de Scala para crear extractores elaborados (emparejadores de patrones), como quizás el más famoso empleado en la API de cuasiquotes de las macros de Scala.

Dado que n"p0${i0}p1" desaparece del new StringContext("p0", "p1").n(i0) , quizás no sea sorprendente que la funcionalidad del extractor esté habilitada al proporcionar una conversión implícita de StringContext a una clase con propiedad n de un tipo que define un método unapply o unapplySeq .

Como ejemplo, considere el siguiente extractor que extrae segmentos de ruta al construir una expresión regular a partir de las partes StringContext . Luego podemos delegar la mayor parte del trabajo pesado al método unapplySeq proporcionado por el resultado 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 _ => ???
}

Tenga en cuenta que el objeto de path también podría definir un método de apply para comportarse como un interpolador regular también.

Interpolación de cuerdas sin procesar

Puede utilizar el interpolador en bruto si desea que una cadena se imprima tal como está y sin ningún escape de literales.


println(raw"Hello World In English And French\nEnglish:\tHello World\nFrench:\t\tBonjour Le Monde")

Con el uso del interpolador en bruto , debería ver lo siguiente impreso en la consola:


Hello World In English And French\nEnglish:\tHello World\nFrench:\t\tBonjour Le Monde

Sin el interpolador en bruto , \n \t se habrían escapado.


println("Hello World In English And French\nEnglish:\tHello World\nFrench:\t\tBonjour Le Monde")

Huellas dactilares:


Hello World In English And French
English:       Hello World
French:        Bonjour Le Monde


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow