问题描述
从 Scala 2.10 开始,字符串插值 在 Scala 中可用
String interpolation is available in Scala starting Scala 2.10
这是一个基本的例子
val name = "World" //> name : String = World
val message = s"Hello $name" //> message : String = Hello World
我想知道是否有办法进行动态插值,例如以下(不编译,仅用于说明目的)
I was wondering if there is a way to do dynamic interpolation, e.g. the following (doesn't compile, just for illustration purposes)
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)
有没有办法动态"评估这样的字符串?(或者它本质上是错误的/不可能的)
Is there a way to "dynamically" evaluate a String like that? (or is it inherently wrong / not possible)
s
究竟是什么? (显然它是 StringContext
上的一个方法),而不是一个对象(如果是,它会抛出一个不同的编译错误比未找到我认为)
And what is s
exactly? (apparently it is a method on StringContext
), and not an object (if it was, it would have thrown a different compile error than not found I think)
推荐答案
s
实际上是 StringContext
上的一个方法(或者可以从 StringContext
).当你写
s
is actually a method on StringContext
(or something which can be implicitly converted from StringContext
). When you write
whatever"Here is text $identifier and more text"
编译器将其脱糖
StringContext("Here is text ", " and more text").whatever(identifier)
默认情况下,StringContext
为您提供 s
、f
和 raw
* 方法.
By default, StringContext
gives you s
, f
, and raw
* methods.
如您所见,编译器自己挑选名称并将其提供给方法.由于这是在编译时发生的,因此您无法明智地动态执行此操作——编译器在运行时没有关于变量名称的信息.
As you can see, the compiler itself picks out the name and gives it to the method. Since this happens at compile time, you can't sensibly do it dynamically--the compiler doesn't have information about variable names at runtime.
但是,您可以使用变量,因此您可以交换所需的值.默认的 s
方法只调用 toString
(正如你所期望的),所以你可以玩像
You can use vars, however, so you can swap in values that you want. And the default s
method just calls toString
(as you'd expect) so you can play games like
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 调用了).
(0 was already called by the REPL in this example).
这大概是你能做的最好的了.
That's about the best you can do.
*
*
这篇关于Scala 2.10 中的字符串插值 - 如何插入字符串变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!