Scala中的嵌套字符串插值

时间:2018-07-13 14:06:22

标签: scala string-interpolation

我正在RDBMS上执行查询,并以字符串形式获取结果。字符串看起来像这样:

val DBASE = "my_database"
val FREQ = "monthly"
val queryResult: String = sqlContext.read.jdbc(...).collect.map(...).first
// queryResult = Database is $$${DBASE} and frequency is $$${FREQ}

接下来,我将$$$替换为$,所以剩下的内容如下:

queryResult = "Database is ${DBASE} and frequency is ${FREQ}"

如何在DBASEFREQ上使用字符串插值?我尝试过:

val substituted = f"${queryResult}"

val substituted = s"${queryResult}"

但是变量没有被替换。除了使用以下内容,我还能做其他事情吗?

queryResult.replaceAll("\\$\\{DBASE\\}", DBASE).replaceAll(...)

3 个答案:

答案 0 :(得分:4)

一种选择是让脚本编写模板:

     ________ ___   / /  ___  
    / __/ __// _ | / /  / _ | 
  __\ \/ /__/ __ |/ /__/ __ | 
 /____/\___/_/ |_/____/_/ | | 
                          |/  version 2.12.6

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

scala> val se = new ScriptEngineManager().getEngineByName("scala")
se: javax.script.ScriptEngine = scala.tools.nsc.interpreter.Scripted@6549ce71

scala> val b = se.createBindings
b: javax.script.Bindings = javax.script.SimpleBindings@2648aa1b

scala> b.put("DBASE", "my_db")
res0: Object = null

scala> b.put("FREQ", "monthly")
res1: Object = null

scala> se.eval("""s"Db is $DBASE, freq is $FREQ"""", b)
res2: Object = Db is my_db, freq is monthly

绑定对象的类型不正确,但是您可以进行强制转换或具有什么内容并进行更多计算:

scala> se.eval("""s"Db is $DBASE, freq is ${FREQ.toString * 2}"""", b)
res4: Object = Db is my_db, freq is monthlymonthly

答案 1 :(得分:1)

Scala的字符串插值

s"Database is ${DBASE} and frequency is ${FREQ}"

本质上只是StringContext上方法调用的语法。像这样

StringContext("Database is ", " and frequency is ",  "").s(DBASE, FREQ)

虽然理论上您可以将字符串"Database is ${DBASE} and frequency is ${FREQ}"分割成适合StringContext的段,然后在某个地方查找变量DBASEFREQ,但看起来立即replaceAll$$${DBASE}出现$$${FREQ}很容易。

答案 2 :(得分:0)

我认为不可能动态地对字符串进行插值,因为它发生在编译时本身。

1)字符串插值发生在编译时,因此编译器通常没有足够的信息来插值s(queryResult)。根据{{​​3}},它期望一个字符串文字。

2)在文档的“高级用法”下,说明了形式为id“ Hello $ name”的表达式。在编译时被转换为新的StringContext(“ Hello”,“。”)。 id(名称)。

因此您可以创建类似

StringContext("Database is ", " and frequency is ",  "").s(DBASE, FREQ)

将替代语法糖。希望有帮助。