我想定義一個Scala val是一個字符串,其值是一個文本文件的全部內容,在編譯時間處讀取。所以,編譯後,這應該只是一個字符串常量。什麼是在編譯時(在Scala中)將字符串常量定義爲文件內容的簡單方法?
我覺得這應該是簡單的,例如,斯卡拉宏,但到目前爲止我無法弄清楚如何簡單地得到字符串值。
我想定義一個Scala val是一個字符串,其值是一個文本文件的全部內容,在編譯時間處讀取。所以,編譯後,這應該只是一個字符串常量。什麼是在編譯時(在Scala中)將字符串常量定義爲文件內容的簡單方法?
我覺得這應該是簡單的,例如,斯卡拉宏,但到目前爲止我無法弄清楚如何簡單地得到字符串值。
你可以在編譯時執行一個命令:source generation task;這裏是從這些文檔複製的簡單示例。根據需要將此文件內容轉儲到對象的val字段中並不難。
sourceGenerators in Compile += Def.task {
val file = (sourceManaged in Compile).value/"demo"/"Test.scala"
IO.write(file, """object Test extends App { println("Hi") }""")
Seq(file)
}.taskValue
正如你可以編寫一個插件SBT一種解決方法(我假設你與SBT建設項目)用於這一目的。
考慮這個例子:
infoFiles := {
val base = (baseDirectory in Compile).value
val file = base/"project"/"BuildInfo.scala"
val content = "package projectbuildinfo\n" +
"object BuildInfo {\n" +
"val name = \"" + name.value + "\"\n" +
"val version = \"" + version.value + "\"\n" +
"val artifact = \"" + (artifactPath in (Compile, packageBin)).value.getPath.dropRight(3) + "war" + "\"\n" +
"val artifactName = \"" + (artifactPath in (Compile, packageBin)).value.getName.dropRight(3) + "war" + "\"\n" +
"}\n"
IO.write(file, content)
Seq(file)
},
sourceGenerators in Compile <+= infoFiles,
此任務每次構建產生BuildInfo.scala
。您基本上可以讀取您的文件並將其內容存儲在Scala類文件中。
@ som-snytt確定:) – leshkin
簡單的宏。這可能在某個地方存在。但我需要這個練習。
scala> import reflect.macros.blackbox.Context
import reflect.macros.blackbox.Context
scala> import language.experimental.macros
import language.experimental.macros
scala> import scala.io._
import scala.io._
scala> :pa
// Entering paste mode (ctrl-D to finish)
class S(val c: Context) {
import c._, universe._
def smac(file: c.Expr[String]): c.Expr[String] = file.tree match {
case Literal(Constant(s: String)) =>
val res = Source.fromFile(s, "UTF-8").getLines.mkString("\n")
c.Expr[String](Literal(Constant(res)))
}}
// Exiting paste mode, now interpreting.
defined class S
scala> def f(file: String): String = macro S.smac
defined term macro f: (file: String)String
scala> f("text.txt")
res3: String = Now is the time for jumping over dogs.
或者,quasiquoting結果:
class S(val c: Context) {
import c._, universe._
def smac(file: c.Expr[String]) = file.tree match {
case Literal(Constant(s: String)) =>
val res = Source.fromFile(s, "UTF-8").getLines.mkString("\n")
q"$res"
}}
爲什麼不只是閱讀從資源文件這個值被編譯到罐子? – Maxim
@Maxim「字符串常量」的常量部分。 –
@ som-snytt -val foo = readFromFile – Maxim