字符串插值是 scala 2.10.0 开始引入的一个新的概念,就是能够让用户在字符串中嵌入变量引用。
从而可以让用户用数据来构造字符串。
比如 s interpolator,允许直接在字符串中使用变量和计算表达式:
val name = "Ldpe2G"
println(s"Hello, $name") // Hello, Ldpe2G
println(s"1 + 1 = ${1 + 1}") // 1 + 1 = 2
已经提供的interpolator还有f, raw等
参考:http://docs.scala-lang.org/overviews/core/string-interpolation.html
下面我们来看看如何自定义一个字符串插值,比如,从一个字符串中找到所有的email地址,
虽然用字符串插值来实现这个功能可能是多此一举,写个函数就可以解决。我这里只是为了
举例如何自定义字符串插值。
import scala.language.experimental._
object EmailTest {
def main(args: Array[String]) = {
val email = "test@gmail.com,test@163.com:fakee3rerw@qq.com"
//为StringContext添加了一个emails方法
//见下面的 implicit class EmailHelper
val emails = emails"测试${email}测试"
emails.filter(!_.equals("")).foreach(println)
}
//email正则表达式,取自 http://tool.oschina.net/
val emailR = """[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?""".r
implicit class EmailHelper(val sc: StringContext) extends AnyVal {
def emails(args: Any*): List[String] = {
val strings = sc.parts.iterator
val expressions = args.iterator
val emails1 = (List[String]() /: strings)((acc, elem) => {
val mats = emailR.findAllIn(elem) mkString(",") split(",")
acc ::: mats.toList
})
val emails2 = (List[String]() /: expressions)((acc, elem) => {
val mats = emailR.findAllIn(sc.s(elem)) mkString(",") split(",")
acc ::: mats.toList
})
emails1 ::: emails2
}
}
}
代码解释:
下面一句代码:
emails"测试${email}测试"
被编译器重写为:
new EmailHelper(new StringContext("测试", "测试")).emails(email)
字符串插值和scala macro结合起来还可以实现很多功能。比如在编译时期判断字符串是否一个合法的email地址。
由于macro我还在学习中,等学习完了再写一篇博客。