Scala 中的嵌套字符串插值
Nested String Interpolation in Scala
我正在 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}"
和
val substituted = s"${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)
虽然理论上您可以将字符串 "Database is ${DBASE} and frequency is ${FREQ}"
拆分为适合 StringContext
的片段,然后在某处查找变量 DBASE
和 FREQ
,但似乎立即 replaceAll
出现 $$${DBASE}
和 $$${FREQ}
要容易得多。
我认为不可能动态地插入一个字符串,因为它发生在编译时本身。
1) 字符串插值发生在编译时,因此编译器通常没有足够的信息来插值s(queryResult)。根据 https://docs.scala-lang.org/sips/string-interpolation.html.
,它需要一个字符串文字
2) 在文档的高级用法下,解释了形式为 id"Hello $name ." 的表达式在编译时被转换为 new StringContext("Hello", ".")。 id(名字).
所以你可以创建类似
的东西
StringContext("Database is ", " and frequency is ", "").s(DBASE, FREQ)
这将替代语法糖。希望对您有所帮助。
一种选择是让脚本编写您的模板:
________ ___ / / ___
/ __/ __// _ | / / / _ |
__\ \/ /__/ __ |/ /__/ __ |
/____/\___/_/ |_/____/_/ | |
|/ 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
我正在 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}"
和
val substituted = s"${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)
虽然理论上您可以将字符串 "Database is ${DBASE} and frequency is ${FREQ}"
拆分为适合 StringContext
的片段,然后在某处查找变量 DBASE
和 FREQ
,但似乎立即 replaceAll
出现 $$${DBASE}
和 $$${FREQ}
要容易得多。
我认为不可能动态地插入一个字符串,因为它发生在编译时本身。
1) 字符串插值发生在编译时,因此编译器通常没有足够的信息来插值s(queryResult)。根据 https://docs.scala-lang.org/sips/string-interpolation.html.
,它需要一个字符串文字2) 在文档的高级用法下,解释了形式为 id"Hello $name ." 的表达式在编译时被转换为 new StringContext("Hello", ".")。 id(名字).
所以你可以创建类似
的东西StringContext("Database is ", " and frequency is ", "").s(DBASE, FREQ)
这将替代语法糖。希望对您有所帮助。
一种选择是让脚本编写您的模板:
________ ___ / / ___
/ __/ __// _ | / / / _ |
__\ \/ /__/ __ |/ /__/ __ |
/____/\___/_/ |_/____/_/ | |
|/ 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