Lai*_*uan 6 debugging scala compiler-directives scala-macros
在C++中我可以写:
#ifdef DEBUG
cout << "Debugging!" << endl;
Run Code Online (Sandbox Code Playgroud)
Scala中有没有相应的东西?
传统的习语是@elidable.
scaladoc涵盖了您的传统用例:
http://www.scala-lang.org/api/current/scala/annotation/elidable.html
C preprocesser #ifdef的等效形式是Scala宏:
package app.macros.log
import scala.language.experimental.macros
import reflect.macros.Context
object SimpleMacroLogger {
private val on = true
def info(msg: String): Unit = macro info_impl
def info_impl(c: Context)(msg: c.Expr[String]): c.Expr[Unit] = {
import c.universe._
if (on) {
reify {
println(msg.splice)
}
} else {
reify {
// Nothing
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
与...一起使用
import app.macros.log.{SimpleMacroLogger => log}
object SimpleMacroLoggerDemo extends App {
log.info("Hello")
}
Run Code Online (Sandbox Code Playgroud)
代码要复杂得多,但它的用法更优越:不需要周围的#ifdef/#endif等.所以它不会使你的代码混乱.
如果设置上,以虚假,宏完全消除记录.
reify中的任何内容都将进入生成的字节代码,其他代码将在编译时运行.这尤其适用于如果(上)....
如果您希望代码仅在满足某些条件时执行,可以使用标准 if 块:
if (SystemProperties.get("debug.mode").exists(_ == "true") {
println("Debugging!")
}
Run Code Online (Sandbox Code Playgroud)
如果您出于某种原因担心该语句甚至不应该出现在编译输出中,那么您可以使用带有编译时常量表达式的 if 块。在这些情况下,javac/scalac 将正确推断条件永远不会为真,因此甚至不包含该块的字节码。(显然,您需要修改您的构建,以便为调试构建引入常量“true”,为生产构建引入常量“false”。)
object Constants {
final val DEBUG = false
}
// ...
if (Constants.DEBUG) {
println("Debugging!")
}
Run Code Online (Sandbox Code Playgroud)