Scala Language
String Interpolation
Suche…
Bemerkungen
Diese Funktion ist in Scala 2.10.0 und höher verfügbar.
Hallo String Interpolation
Der s- Interpolator erlaubt die Verwendung von Variablen innerhalb eines Strings.
val name = "Brian"
println(s"Hello $name")
druckt "Hallo Brian" auf die Konsole, wenn er ausgeführt wird.
Formatierte String-Interpolation mit dem f-Interpolator
val num = 42d
Mit f werden zwei Nachkommastellen für num
gedruckt
println(f"$num%2.2f")
42.00
Drucken Sie num
wissenschaftlicher Notation mit e
println(f"$num%e")
4.200000e+01
num
in hexadezimal mit a num
println(f"$num%a")
0x1.5p5
Weitere Formatzeichenfolgen finden Sie unter https://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#detail
Ausdruck in String-Literalen verwenden
Sie können geschweifte Klammern verwenden, um Ausdrücke in String-Literale zu interpolieren:
def f(x: String) = x + x
val a = "A"
s"${a}" // "A"
s"${f(a)}" // "AA"
Ohne die geschweiften Klammern interpoliert scala den Bezeichner nur nach dem $
(in diesem Fall f
). Da es keine implizite Konvertierung von f
in einen String
gibt, ist dies in diesem Beispiel eine Ausnahme:
s"$f(a)" // compile-time error (missing argument list for method f)
Benutzerdefinierte String-Interpolatoren
Es ist möglich, zusätzlich zu den integrierten Stringinterpolatoren eigene Zeichenfolgen zu definieren.
my"foo${bar}baz"
Wird vom Compiler erweitert um:
new scala.StringContext("foo", "baz").my(bar)
scala.StringContext
hat keine my
Methode und kann daher durch implizite Konvertierung bereitgestellt werden. Eine benutzerdefinierte Interpolator mit dem gleichen Verhalten wie das Builtin s
Interpolator würde dann wie folgt umgesetzt werden:
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
}
}
Und die Interpolation, die my"foo${bar}baz"
hätte:
new MyInterpolation(new StringContext("foo", "baz")).my(bar)
Beachten Sie, dass die Argumente oder der Rückgabetyp der Interpolationsfunktion nicht eingeschränkt sind. Dies führt uns zu einem dunklen Pfad, auf dem die Interpolationssyntax kreativ zum Erstellen beliebiger Objekte verwendet werden kann, wie im folgenden Beispiel veranschaulicht:
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
Stringinterpolatoren als Extraktoren
Es ist auch möglich, die String-Interpolationsfunktion von Scala zu verwenden, um aufwendige Extraktoren (Pattern-Matcher) zu erstellen, wie sie vielleicht am bekanntesten in der Quasiquoten-API von Scala-Makros verwendet werden.
Da n"p0${i0}p1"
in den new StringContext("p0", "p1").n(i0)
ist new StringContext("p0", "p1").n(i0)
, ist es nicht überraschend, dass die Extraktorfunktionalität durch die implizite Konvertierung von StringContext
in eine Klasse mit aktiviert wird Eigenschaft n
eines Typs, der eine nicht unapply
oder unapplySeq
Methode definiert.
Betrachten Sie als Beispiel den folgenden Extraktor, der StringContext
extrahiert, indem Sie einen regulären Ausdruck aus den StringContext
Teilen StringContext
. Wir können dann den Großteil des schweren unapplySeq
an die unapplySeq
Methode unapplySeq
, die von der resultierenden scala.util.matching.Regex bereitgestellt wird:
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 _ => ???
}
Beachten Sie, dass das path
auch eine apply
Methode definieren kann apply
um sich auch als regulärer Interpolator zu verhalten.
Raw String Interpolation
Sie können das Roh - Interpolator verwenden , wenn Sie eine Zeichenfolge gedruckt werden soll , wie und ohne Entkommen von Literalen.
println(raw"Hello World In English And French\nEnglish:\tHello World\nFrench:\t\tBonjour Le Monde")
Mit dem Einsatz des Roh - Interpolator, sollten Sie die folgenden gedruckt in der Konsole angezeigt:
Hello World In English And French\nEnglish:\tHello World\nFrench:\t\tBonjour Le Monde
Ohne das Roh - Interpolator, \n
und \t
entgangen worden wäre.
println("Hello World In English And French\nEnglish:\tHello World\nFrench:\t\tBonjour Le Monde")
Drucke:
Hello World In English And French
English: Hello World
French: Bonjour Le Monde