今度は、String Interpolationです。
http://docs.scala-lang.org/overviews/core/string-interpolation.html
こちらも、日本語訳が。
http://docs.scala-lang.org/ja/overviews/core/string-interpolation.html
文字列リテラルの前に、補間子というものを入れることでデータから文字列を作成する機構なんだそうで。これは、実例を見た方が早いですね。補間子は、s、f、rawの3つがあります。
例えば、
s"..."
というような書き方になります。
なお、補間子が定義されているのはscala.StringContextになるので、最終的にはここを見るんでしょうね。
http://www.scala-lang.org/api/current/index.html#scala.StringContext
s補間子
動的言語のように、文字列中で変数展開を行います。変数展開を行う時は、$変数名、もしくは${変数名}です。
サンプル。
val stringValue = "Hello World" val intValue = 1000 val doubleValue = 10.505 println(s"s format example = $stringValue, $intValue, $doubleValue") println(s"s format example = ${stringValue}, ${intValue}, ${doubleValue}")
実行すると、こうなります。
s format example = Hello World, 1000, 10.505 s format example = Hello World, 1000, 10.505
その他、式を書くことも可能です。
println(s"now = ${new java.util.Date}")
しかも、実行時に解釈しているのではないようなので、こんな風に間違えると
println(s"now = ${new java.util.Dat}")
コンパイルエラーになります。
error: type Dat is not a member of package java.util println(s"now = ${new java.util.Dat}") ^ one error found
すげー。
もちろん、変数展開の場合もその対象の変数がなかったりするとエラーになります。
error: not found: value hoge println(s"$hoge") ^ one error found
f補間子
変数展開と、java.util.Formatterで解釈できるフォーマット指定を使える補間子です。
val stringValue = "Hello World" val intValue = 1000 val doubleValue = 10.505 println(f"f format example = $stringValue%s, $intValue%,3d, $doubleValue%.2f") println(f"f format example = ${stringValue}%s, ${intValue}%06d, ${doubleValue}%.2f")
実行すると
f format example = Hello World, 1,000, 10.51 f format example = Hello World, 001000, 10.51
となります。
こちらも、s補間子と同様存在しない変数などを展開しようとすると、コンパイルエラーになります。${}中に、式を埋め込むことができる点も同様です。
その他、書式に対して型チェックをしているようで、こんな風に型と書式の指定を間違えると
val doubleValue = 10.505 println(f"$doubleValue%d")
コンパイルエラーになります。
error: type mismatch; found : Double required: Int println(f"$doubleValue%d")
raw補間子
s補間子とほぼ同じらしいですが、エスケープを実行しないことが異なるそうで。こんなサンプルを実行すると
val stringValue = "Hello World" println(raw"\r\n\t $stringValue")
\rとか\nとかがそのまま出力されます。
\r\n\t Hello World
どこで使うのか?正規表現とか?
println(raw"\d+".r.findFirstIn("100"))
まあ、この場合はこれでもいいですよね…。
println("""\d+""".r.findFirstIn("100"))
とまあ、こんな感じの使い方をするようです。自分で補間子を定義することもできるようですが、ちょっと省略…。
しかしまあ、こういう書き方してると、どうしてもPythonを連想しますね。
ちょっと気になること
$をエスケープするには?
$$とすればいいみたいです。
val stringValue = "Hello World" println(s"$stringValue $$stringValue")
結果。
Hello World $stringValue
自分でString Interpolation(補間子)を定義するには?
別エントリを起こしました。こちらを参照してください。
ScalaのString Interpolationを自分で書いて試してみる
http://d.hatena.ne.jp/Kazuhira/20131206/1386345512
また、JPAのJPQLにString Interpolationを適用した例も、書いてみました。
JPQLとString Interpolationを使って遊んでみる
http://d.hatena.ne.jp/Kazuhira/20131214/1387016162
"をエスケープするには?
追記)
「"」をエスケープするには、raw string literalと合わせて使えばよいみたいです。
val str = "quote escaped" println(s"""this is \"$str\" s string interpolation""") println(f"""this is \"$str\" f string interpolation""") println(raw"""this is "$str" raw string interpolation""")
結果。
this is "quote escaped" s string interpolation this is "quote escaped" f string interpolation this is "quote escaped" raw string interpolation
raw補間子は、何もしなくていいです。
この後にも書いている
https://issues.scala-lang.org/browse/SI-6476
にすでにこの対処が記載されていたことを、だいぶ後になって知りました。
*ここから先の「"」のエスケープ方法は、以前に書いた内容です
これ、最初にハマりました。
こういうやつを書くと
println(s"this is \"s\" string interpolation")
なんと、文字列リテラルの終わりが分からなくなっているようで、コンパイルエラーになります。
error: ')' expected but string literal found. println(s"this is \"s\" string interpolation")
これは、f補間子もraw補間子も同じです。
えー、どうすんの?と思って調べたら、すでに挙がってました。
https://issues.scala-lang.org/browse/SI-6476
こう書け、と。
s"${'"'}"
マジ?${}内に式が埋められることを利用したやり方のようですが…。
ちょっと試してみましょう。
println(s"this is ${'"'}s${'"'} string interpolation") println(f"this is ${'"'}f${'"'} string interpolation") println(raw"this is ${'"'}raw${'"'} string interpolation")
実行。
this is "s" string interpolation this is "f" string interpolation this is "raw" string interpolation
…動きました。
動いたはいいんですけど、エディタの動きがおかしくなるんですが…。
それか、
s"\042"
と指定すれば動きます。他に方法はないんでしょうか…。
こういう書き方するくらいなら、個人的にはもう変数展開した方が見やすい気がするのですが。
var qq = '"' println(s"this is ${qq}s${qq} string interpolation")