Recherche…


Remarques

Cette fonctionnalité existe dans Scala 2.10.0 et supérieur.

Bonjour l'interpolation de chaîne

L'interpolateur s permet l'utilisation de variables dans une chaîne.

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

Imprime "Hello Brian" sur la console quand il est exécuté.

Interpolation de chaînes formatées à l'aide de l'interpolateur f

val num = 42d

Imprimer deux décimales pour num utilisant f

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

Imprimer num utilisant la notation scientifique en utilisant e

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

Imprimer num en hexadécimal avec un

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

D'autres chaînes de format sont disponibles à l' adresse https://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#detail

Utiliser l'expression dans les littéraux de chaîne

Vous pouvez utiliser des accolades pour interpoler des expressions dans des littéraux de chaîne:

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

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

Sans les accolades, scala n'interpolerait que l' identifiant après le $ (dans ce cas, f ). Comme il n'y a pas de conversion implicite de f en String il s'agit d'une exception dans cet exemple:

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

Interpolateurs de chaînes personnalisés

Il est possible de définir des interpolateurs de chaînes personnalisés en plus des interpolateurs intégrés.

my"foo${bar}baz"

Est développé par le compilateur pour:

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

scala.StringContext n'a pas my méthode et peut donc être fournie par une conversion implicite. Interpolateur personnalisé avec le même comportement que la fonction interne s l'interpolateur serait alors mis en œuvre comme suit:

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

Et l'interpolation de my"foo${bar}baz" serait destinée à:

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

Notez qu'il n'y a pas de restriction sur les arguments ou le type de retour de la fonction d'interpolation. Cela nous conduit dans une voie sombre où la syntaxe d'interpolation peut être utilisée de manière créative pour construire des objets arbitraires, comme illustré dans l'exemple suivant:

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

Interpolateurs de chaînes comme extracteurs

Il est également possible d'utiliser la fonction d'interpolation de chaîne de Scala pour créer des extracteurs élaborés («Pattern Matcher»), comme peut-être le plus utilisé dans l' API de quasiquotes des macros Scala.

Etant donné que n"p0${i0}p1" desugars à new StringContext("p0", "p1").n(i0) , il n'est peut-être pas surprenant que la fonctionnalité d'extracteur soit activée en fournissant une conversion implicite de StringContext en classe avec propriété n d'un type définissant une méthode unapply ou unapplySeq .

À titre d'exemple, considérons l'extracteur suivant qui extrait des segments de chemin en construisant une expression régulière à partir des parties StringContext . Nous pouvons alors déléguer la plupart des unapplySeq lourdes à la méthode unapplySeq fournie par 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 _ => ???
}

Notez que l'objet path pourrait également définir une méthode apply afin de se comporter comme un interpolateur régulier.

Interpolation de chaîne brute

Vous pouvez utiliser l'interpolateur brut si vous souhaitez qu'une chaîne soit imprimée telle quelle et sans aucune fuite de littéraux.


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

Avec l'utilisation de l'interpolateur brut , vous devriez voir les éléments suivants imprimés dans la console:


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

Sans l'interpolateur brut , \n et \t auraient été échappés.


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

Impressions:


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


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow