Scala中的嵌套字符串插值

Scala中的嵌套字符串插值,scala,string-interpolation,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} 接下来,我将用$替换$$$,因此剩下的内容

我正在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}"
如何在
DBASE
FREQ
上使用字符串插值?我试过:

val substituted = f"${queryResult}"

但这些变量并没有被取代。除了使用以下工具外,我还能做些什么:

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

Scala的字符串插值

s"Database is ${DBASE} and frequency is ${FREQ}"
本质上只是
StringContext
上方法调用的奇特语法。它的意思是

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

虽然理论上可以将字符串
“Database is${DBASE}和frequency is${FREQ}”
拆分为适合
StringContext
的片段,然后在某处查找变量
DBASE
FREQ
,但是
替换所有出现的
$$${DBASE}似乎要容易得多
$${FREQ}
立即执行。

Scala的字符串插值

s"Database is ${DBASE} and frequency is ${FREQ}"
本质上只是
StringContext
上方法调用的奇特语法。它的意思是

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

虽然理论上可以将字符串
“Database is${DBASE}和frequency is${FREQ}”
拆分为适合
StringContext
的片段,然后在某处查找变量
DBASE
FREQ
,但是
替换所有出现的
$$${DBASE}似乎要容易得多
$${FREQ}
立即插入字符串。

我认为不可能动态插入字符串,因为它发生在编译时本身

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

2) 在文档中的“高级用法”下,解释了在编译时将id为“Hello$name.”的表达式转换为新的StringContext(“Hello”,“)。id(名称)

因此,您可以创建类似

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

它将取代语法上的suger。希望能有所帮助。

我认为不可能在编译时动态插入字符串

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

2) 在文档中的“高级用法”下,解释了在编译时将id为“Hello$name.”的表达式转换为新的StringContext(“Hello”,“)。id(名称)

因此,您可以创建类似

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

它将取代语法上的suger。希望这会有所帮助。

一种选择是让脚本完成模板制作:

     ________ ___   / /  ___  
    / __/ __// _ | / /  / _ | 
  __\ \/ /__/ __ |/ /__/ __ | 
 /____/\___/_/ |_/____/_/ | | 
                          |/  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

一种选择是让脚本执行模板:

     ________ ___   / /  ___  
    / __/ __// _ | / /  / _ | 
  __\ \/ /__/ __ |/ /__/ __ | 
 /____/\___/_/ |_/____/_/ | | 
                          |/  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

只是字符串几乎有50000个字符(我需要执行一个参数化SQL查询),所以我认为拆分并使用
StringContext
不是很可行。我想我会使用
replaceAll
。@philantrovert我不知道为什么您试图手动将参数插入到由其他查询返回的查询中。。。看起来像是一个奇怪的严格类型的设计。没有办法使用某种预先准备好的语句吗?没有,查询需要传递到配置单元。只是字符串几乎有50000个字符(我需要执行一个参数化SQL查询),所以我认为拆分并使用
StringContext
不是很可行。我想我会使用
replaceAll
。@philantrovert我不知道为什么您试图手动将参数插入到由其他查询返回的查询中。。。看起来像是一个奇怪的严格类型的设计。没有办法改用某种预先准备好的语句吗?没有,需要将查询传递到配置单元。