Scala 2.10中的string插值 – 如何内插一个stringvariables?
从Scala 2.10开始,Scala中可以使用string插值
这是基本的例子
val name = "World" //> name : String = World val message = s"Hello $name" //> message : String = Hello World
我想知道是否有一种方法来做dynamic插值,例如下面的(不会编译,仅用于说明目的)
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)
-
有没有办法“dynamic”评估一个string呢? (或者它本身是错误的/不可能的)
-
那究竟是什么?
这不是一个方法def( 显然这是一个StringContext
上的方法 ),而不是一个对象(如果是的话,它会引发一个不同的编译错误比我不认为)
s
实际上是一个在StringContext
上的方法(或者可以从StringContext
隐式转换的方法)。 当你写
whatever"Here is text $identifier and more text"
编译器把它parsing成
StringContext("Here is text ", " and more text").whatever(identifier)
默认情况下, StringContext
为你提供了s
, f
和raw
*方法。
正如你所看到的,编译器自己挑出名字并将其提供给方法。 由于这是在编译时发生的,因此不能dynamic地做到这一点 – 编译器在运行时没有关于variables名的信息。
然而,你可以使用variables,所以你可以交换你想要的值。 而默认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
(在这个例子中,REPL已经调用了0)。
这是关于你能做的最好的。
* raw
破碎,直到2.10.1才被固定; 只有variables之前的文本实际上是原始的(没有转义处理)。 所以暂缓使用那个,直到2.10.1出来,或者查看源代码并定义你自己的。 默认情况下,没有转义处理,所以定义你自己很容易。
根据Rex的出色答案,在原始问题的背景下,这是一个可能的解决scheme
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
- string插值发生在编译时,所以编译器通常没有足够的信息来插入
s(str)
。 它期望一个string文字, 根据SIP 。 - 在您链接的文档中,在“ 高级用法”下,解释了表单
id"Hello $name ."
的expression式id"Hello $name ."
在编译时转换为new StringContext("Hello", "."). id(name)
new StringContext("Hello", "."). id(name)
。
请注意, id
可以是通过隐式类引入的用户定义的插补器。 该文档给出了一个json
插补器的例子,
implicit class JsonHelper(val sc: StringContext) extends AnyVal { def json(args: Any*): JSONObject = { ... } }
在当前的实现中,这本质上是不可能的:局部variables名在执行时不可用 – 可以作为debugging符号保留,但也可以被剥离。 (成员variables名称,但这不是你在这里描述的)。