文字列補間は Scalaで利用可能 開始Scala 2.10
これは基本的な例です
val name = "World" //> name : String = World
val message = s"Hello $name" //> message : String = Hello World
動的補間を行う方法があるかどうか疑問に思っていました。以下(説明のためにコンパイルされていません)
val name = "World" //> name : String = World
val template = "Hello $name" //> template : String = Hello $name
//just for illustration:
val message = s(template) //> doesn't compile (not found: value s)
そのような文字列を「動的に」評価する方法はありますか? (またはそれは本質的に間違っている/不可能です)
そして、s
とは正確には何ですか? それはメソッドの定義ではありません ( どうやらそれはStringContext
のメソッドです)、オブジェクトではありません(そうであった場合、とは異なるコンパイルエラーをスローします見つかった私は思う)
s
は、実際にはStringContext
(またはStringContext
から暗黙的に変換できるもの)のメソッドです。あなたが書くとき
whatever"Here is text $identifier and more text"
コンパイラはそれをdesugars
StringContext("Here is text ", " and more text").whatever(identifier)
デフォルトでは、StringContext
はs
、f
、およびraw
*メソッドを提供します。
ご覧のとおり、コンパイラ自体が名前を取り出してメソッドに渡します。これはコンパイル時に発生するため、動的に行うことはできません。コンパイラには実行時の変数名に関する情報がありません。
ただし、varsを使用できるため、必要な値を入れ替えることができます。そして、デフォルトのs
メソッドは、(予想通り)toString
を呼び出すだけなので、次のようなゲームをプレイできます。
class PrintCounter {
var i = 0
override def toString = { val ans = i.toString; i += 1; ans }
}
val pc = new PrintCounter
def pr[A](a: A) { println(s"$pc: $a") }
scala> List("salmon","herring").foreach(pr)
1: salmon
2: herring
(0はすでにREPL)によって呼び出されました)。
それはあなたができる最高のことです。
*raw
は壊れており、2.10.1まで修正される予定はありません。変数の前のテキストのみが実際に生です(エスケープ処理はありません)。そのため、2.10.1がリリースされるまで、その使用を控えるか、ソースコードを確認して独自のコードを定義してください。デフォルトでは、エスケープ処理がないため、独自の定義は非常に簡単です。
レックスの優れた回答に基づく元の質問のコンテキストで、#1の可能な解決策を次に示します
val name = "World" //> name: String = World
val template = name=>s"Hello $name" //> template: Seq[Any]=>String = <function1>
val message = template(name) //> message: String = Hello World
s(str)
を補間するのに十分な情報を持っていません。文字列リテラル SIPによると が必要です。id"Hello $name ."
_形式の式がコンパイル時にnew StringContext("Hello", "."). id(name)
。id
は、暗黙のクラスを通じて導入されたユーザー定義の補間関数である可能性があることに注意してください。ドキュメントはjson
補間器の例を示しています、
_implicit class JsonHelper(val sc: StringContext) extends AnyVal {
def json(args: Any*): JSONObject = {
...
}
}
_
これは、現在の実装では本質的に不可能です。ローカル変数名は実行時に利用できません。デバッグシンボルとして保持されている可能性がありますが、削除されている場合もあります。 (メンバー変数名はそうですが、ここでは説明していません)。