サーチ…


備考

この機能は、Scala 2.10.0以降にあります。

Hello文字列の補間

sインターポレータは、文字列内の変数の使用を許可します。

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

実行時に "Hello Brian"をコンソールに表示します。

fインターポレータを使用した書式付き文字列の補間

val num = 42d

fを使用してnum小数点以下2桁を出力する

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

eを使用して科学記法を使用してnumを出力する

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

印刷numと16進数で

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

その他の書式文字列については、次のURLを参照してください。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.StringContextmyメソッドがありません。したがって、暗黙の変換によって提供できます。組み込み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"補間はmy"foo${bar}baz"ようにdesugarでしょう:

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マクロのquasiquotes APIで最も有名になっているように、Scalaの文字列補間機能を使って精巧な抽出子(パターンマッチャー)を作成することも可能です。

n"p0${i0}p1"new StringContext("p0", "p1").n(i0)に対応していない場合、 StringContextからの暗黙的な変換を提供することによって抽出機能が有効になることは、 unapplyまたはunapplySeqメソッドを定義する型のプロパティn

例として、 StringContext部分から正規表現を構築することによってパスセグメントを抽出する次の抽出プログラムを考えてみましょう。その後、大量の重い吊り上げを、結果として得られるscala.util.matching.Regexが提供するunapplySeqメソッドに委譲できます

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