Zoeken…


Opmerkingen

Deze functie bestaat in Scala 2.10.0 en hoger.

Hallo tekenreeksinterpolatie

Met de s- interpolator kunnen variabelen binnen een string worden gebruikt.

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

drukt "Hallo Brian" af op de console wanneer deze wordt uitgevoerd.

Geformatteerde tekenreeksinterpolatie met de f-interpolator

val num = 42d

Druk twee decimalen af voor num met behulp van f

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

num afdrukken met wetenschappelijke notatie met e

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

num afdrukken in hexadecimaal met een

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

Andere indelingsstrings zijn te vinden op https://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#detail

Expressie gebruiken in letterlijke tekenreeksen

U kunt accolades gebruiken om expressies te interpoleren naar stringliterals:

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

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

Zonder de accolades interpoleert scala de identifier alleen na de $ (in dit geval f ). Aangezien er geen impliciete conversie is van f naar een String dit een uitzondering in dit voorbeeld:

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

Aangepaste stringinterpolators

Het is mogelijk om aangepaste stringinterpolators te definiëren naast de ingebouwde.

my"foo${bar}baz"

Is door de compiler uitgebreid naar:

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

scala.StringContext heeft my methode niet, daarom kan het worden geleverd door impliciete conversie. Een aangepaste interpolator met hetzelfde gedrag als het interne s interpolator zou dan als volgt uitgevoerd:

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

En de interpolatie die my"foo${bar}baz" zou willen:

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

Merk op dat er geen beperking is voor de argumenten of het retourtype van de interpolatiefunctie. Dit leidt ons langs een donker pad waar syntaxis van de interpolatie creatief kan worden gebruikt om willekeurige objecten te construeren, zoals geïllustreerd in het volgende voorbeeld:

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

Stringinterpolators als extractors

Het is ook mogelijk om Scala's stringinterpolatiefunctie te gebruiken om uitgebreide extractors (patroonmatchers) te maken, zoals misschien het meest bekend in de quasiquotes-API van Scala-macro's.

Gezien het feit dat n"p0${i0}p1" naar new StringContext("p0", "p1").n(i0) , is het misschien niet StringContext dat de extractorfunctionaliteit is ingeschakeld door een impliciete conversie van StringContext naar een klasse met eigenschap n van een type dat een unapply of unapplySeq methode unapplySeq .

Beschouw als voorbeeld de volgende extractor die StringContext extraheert door een reguliere expressie te construeren uit de StringContext delen. We kunnen vervolgens het grootste deel van het zware werk delegeren naar de unapplySeq methode die wordt geboden door de resulterende 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 _ => ???
}

Merk op dat het path object kan ook bepalen een apply methode om gedragen als normale interpolator ook.

Ruwe stringinterpolatie

U kunt de onbewerkte interpolator gebruiken als u wilt dat een tekenreeks wordt afgedrukt zoals deze is en zonder letterlijk te ontsnappen.


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

Bij gebruik van de onbewerkte interpolator zou het volgende in de console moeten worden afgedrukt:


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

Zonder de onbewerkte interpolator zouden \n en \t zijn ontsnapt.


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

prints:


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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow