2015-11-18 46 views
1

我想定義一個Scala val是一個字符串,其值是一個文本文件的全部內容,在編譯時間處讀取。所以,編譯後,這應該只是一個字符串常量。什麼是在編譯時(在Scala中)將字符串常量定義爲文件內容的簡單方法?

我覺得這應該是簡單的,例如,斯卡拉宏,但到目前爲止我無法弄清楚如何簡單地得到字符串值。

+0

爲什麼不只是閱讀從資源文件這個值被編譯到罐子? – Maxim

+0

@Maxim「字符串常量」的常量部分。 –

+0

@ som-snytt -val foo = readFromFile – Maxim

回答

6

你可以在編譯時執行一個命令: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 
0

正如你可以編寫一個插件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類文件中。

+0

@ som-snytt確定:) – leshkin

3

簡單的宏。這可能在某個地方存在。但我需要這個練習。

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" 
}} 
相關問題