标量的字符串标量而不是文字标量

时间:2019-07-19 05:49:26

标签: scala

首先道歉,他是Scala的初学者,我找不到这个问题的更好措辞。

我有一个属性文件,需要在其中定义一些参数化的命令(或sql查询)。以下是一个示例:

[section abc]
stage: StageA
query: Select count(*) FROM tableA WHERE account_id=${account_id} AND dt=$dt AND source=$source

[section def]
stage: StageB
query: Select count(*) FROM tableB WHERE event_date=${event_date} AND template=$template

在我的代码中,我有一个配置对象(考虑一个Map),该对象具有查询字符串(account_idsourcedt,{{1 }},event_date等)。读取属性文件后,我需要替换查询字符串中的所有宏。为此,我想编写一个具有以下签名的函数:

template

应返回查询文本,其中的宏被配置中的值替换。我尝试编写自己的String Interpolator,但是没有用。还有什么可以尝试的吗?

1 个答案:

答案 0 :(得分:1)

通过字符串插值,编译器将String文字切成一部分,然后再通过StringContext发送它们进行重组。编译器不会对变量中的字符串值执行此操作,因此您必须自己剪切。

def resolve_query(query: String, config: Map[String, Any]): String =
  "(.*)\\$\\{([^}]+)}(.*)".r
                          .findFirstMatchIn(query)
                          .fold(query){ m =>
    resolve_query(StringContext(m.group(1), m.group(3))
                              .s(config.getOrElse(m.group(2), "unknown"))
                 ,config)
  }

测试:

resolve_query(
  "Select count(*) FROM tableA WHERE account_id=${account_id} AND source=${source}"
 ,Map("account_id" -> 47, "source" -> "UK")
             )
//res0: String = Select count(*) FROM tableA WHERE account_id=47 AND source=UK

您会注意到,我仅实现了更简单的${braces}分隔表格。 $dollar带分隔符的表单虽然没有那么复杂,但是允许两者(一个或一个或多个)的工作量比我现在愿意输入的还要多。