2016-04-15 24 views
1

Scalaの文字列補間メカニズムには何か基本的なものがありません。私がしたいこと:Scala String変数が埋め込まれた既存の文字列のインターポレータ

// this could come from a config file, string here to demo 
val brown = "BROWN" 
val cow = "Moo" 
val replaceInMe = "How Now ${brown} ${cow}" 

//this does what I eventually want: 
val output = s"How Now ${brown} ${cow}" 

//But, since the variables 'brown' and 'cow' are defined, 
//I really wold like to be able to do something like: 
val output = s(replaceInMe) 

これは可能ですか?

EDIT:以下の最初の回答に基づいて、変数replaceInMeを入力する必要があります。ここでは文字列として定義していますが、実際は設定ファイルから読み込んだ行です。

答えて

5

号。

コンパイラが見ているとき、これは次のとおりです。値がそうで設定されているため、コンパイラは、任意の識別子でこれを行うことはできません

new StringContext("How Now ", " ", "").s(brown, cow) 

s"How Now ${brown} ${cow}" 

それはに変換します実行時間、およびコンパイル時間ではありません。 replaceInMeが外部ファイルから取得された値であるとします。外部ファイルの文字列は、プログラム内の実行時変数をどのように知ることができますか?定義されていない場合はどうなりますか?文字列補間では、これはコンパイルエラーによって処理されますが、これは明らかに実行時には発生しません。実行時に、欠損値に対処する別の方法が必要です。

これを処理するには、ある種の設定ライブラリを使用する方がよいでしょう。

+0

それは分かりました。ありがとう! – banncee

1

はい、可能です。 replaceInMeの前にvalの茶色と牛を定義するだけです:

あなたのケースでは、評価後にreplaceInMeを変更できないため、機能しません。その値の型。詳細については

val brown = "BROWN" 
    val cow = "Moo" 
    // this could come from a config file, string here to demo 
    val replaceInMe = s"How Now ${brown} ${cow}" 
    println(replaceInMe) 

documentationはあなたが唯一の任意の文字列オブジェクトを文字列リテラルでこれを行うことはできず、それが明確なことになり http://docs.scala-lang.org/overviews/core/string-interpolation.html

+0

おかげで、上記の私の編集を参照してください。 – banncee

2

もう少し待ってください!コンパイラはテンプレートエンジンです!

scala> import javax.script._ 
import javax.script._ 

scala> val se = new ScriptEngineManager().getEngineByName("scala") 
se: javax.script.ScriptEngine = [email protected] 

scala> val animal = new { override def toString = "cow" } // some value 
animal: AnyRef = cow 

scala> se.put("animal", animal) 

scala> val template = "I see a $animal" 
template: String = I see a $animal 

scala> se.eval(s"""s"$template, she said."""") 
res1: Object = I see a cow, she said. 

または、

scala> val sc = se.asInstanceOf[ScriptEngine with Compilable] 
sc: javax.script.ScriptEngine with javax.script.Compilable = [email protected] 

scala> val cs = sc.compile(s"""s"$template, she said."""") 
cs: javax.script.CompiledScript = [email protected] 

scala> cs.eval() 
res4: Object = I see a cow, she said. 

scala> val ctx = sc.createBindings() 
ctx: javax.script.Bindings = [email protected]  

scala> ctx.put("animal", "frog") 
res5: Object = null 

scala> cs.eval(ctx) 
res6: Object = I see a frog, she said. 

ただ、 "コンパイル時には、" 相対的であることを示すために:

scala> val cs = sc.compile("""s"There's no such $thing in scope."""") 
<console>:12: error: not found: value thing 
     s"There's no such $thing in scope." 
         ^
javax.script.ScriptException: compile-time error 
    at scala.tools.nsc.interpreter.Scripted.scala$tools$nsc$interpreter$Scripted$$$anonfun$7(Scripted.scala:113) 
    at scala.tools.nsc.interpreter.Scripted$DynamicContext.apply(Scripted.scala:38) 
    at scala.tools.nsc.interpreter.Scripted.compile(Scripted.scala:101) 
    at scala.tools.nsc.interpreter.Scripted.compile(Scripted.scala:124) 
    ... 30 elided 
+0

非常に有益なレッスンをありがとう。私のScalaの給与等級以上です... – banncee

関連する問題