我想知道在scala中进行字符串插值时是否有任何保留缩进的方法.基本上,我想知道我是否可以介入我自己的StringContext.宏将解决这个问题,但我想等到他们正式.
这就是我要的:
val x = "line1 \nline2"
val str = s"> ${x}"
Run Code Online (Sandbox Code Playgroud)
str应该评估为
> line1
line2
Run Code Online (Sandbox Code Playgroud)
回答我的问题,并将Daniel Sobral非常有用的答案转换为代码.希望它对具有相同问题的其他人有用.我没有使用隐式类,因为我仍然在2.10之前.
import Indenter._
并使用字符串插值 e" $foo "
import Indenter._
object Ex extends App {
override def main(args: Array[String]) {
val name = "Foo"
val fields = "x: Int\ny:String\nz:Double"
// fields has several lines. All of them will be indented by the same amount.
print (e"""
class $name {
${fields}
}
""")
}
}
Run Code Online (Sandbox Code Playgroud)
应该打印
class Foo
x: Int
y: String
z: Double
Run Code Online (Sandbox Code Playgroud)
class IndentStringContext(sc: StringContext) {
def e(args: Any*):String = {
val sb = new StringBuilder()
for ((s, a) <- sc.parts zip args) {
sb append s
val ind = getindent(s)
if (ind.size > 0) {
sb append a.toString().replaceAll("\n", "\n" + ind)
} else {
sb append a.toString()
}
}
if (sc.parts.size > args.size)
sb append sc.parts.last
sb.toString()
}
// get white indent after the last new line, if any
def getindent(str: String): String = {
val lastnl = str.lastIndexOf("\n")
if (lastnl == -1) ""
else {
val ind = str.substring(lastnl + 1)
if (ind.trim.isEmpty) ind // ind is all whitespace. Use this
else ""
}
}
}
object Indenter {
// top level implicit defs allowed only in 2.10 and above
implicit def toISC(sc: StringContext) = new IndentStringContext(sc)
}
Run Code Online (Sandbox Code Playgroud)
您可以编写自己的插补器,并且可以使用自己的插值器遮挡标准插值器.现在,我不知道你的例子背后的语义是什么,所以我甚至都不去尝试.
在Slideshare或SpeakerDeck上查看我在Scala 2.10上的演示文稿,因为它们包含了可以编写/覆盖插补器的所有方式的示例.从幻灯片40开始(现在 - 演示文稿可能会更新,直到2.10终于出来).
归档时间: |
|
查看次数: |
1127 次 |
最近记录: |