Scala:代码仅在调试时运行(#ifdef等效?) 在C++中,我可以写: #ifdef DEBUG cout << "Debugging!" << endl; #ifdef调试 cout
如果希望代码仅在某些条件成立时执行,可以使用标准的If块:Scala:代码仅在调试时运行(#ifdef等效?) 在C++中,我可以写: #ifdef DEBUG cout << "Debugging!" << endl; #ifdef调试 cout,debugging,scala,compiler-directives,scala-macros,Debugging,Scala,Compiler Directives,Scala Macros,如果希望代码仅在某些条件成立时执行,可以使用标准的If块: if (SystemProperties.get("debug.mode").exists(_ == "true") { println("Debugging!") } 如果出于任何原因担心该语句不应该出现在编译后的输出中,那么可以使用带有编译时常量表达式的If块。在这些情况下,javac/scalac将正确地推断出该条件永远不会为真,因此甚至不包括块的字节码。(显然,您需要修改您的构建,以便为调试构建引入一个常量“true”,为
if (SystemProperties.get("debug.mode").exists(_ == "true") {
println("Debugging!")
}
如果出于任何原因担心该语句不应该出现在编译后的输出中,那么可以使用带有编译时常量表达式的If块。在这些情况下,javac/scalac将正确地推断出该条件永远不会为真,因此甚至不包括块的字节码。(显然,您需要修改您的构建,以便为调试构建引入一个常量“true”,为产品构建引入一个常量“false”。)
C预处理器ifdef的等效形式是Scala宏:
配合使用
import app.macros.log.{SimpleMacroLogger => log}
object SimpleMacroLoggerDemo extends App {
log.info("Hello")
}
编写代码要复杂得多,但它的使用非常优越:不需要围绕#ifdef/#endif等,因此它不会使代码混乱
如果设置为false,则宏将完全删除日志记录
具体化中的任何内容都将进入结果字节码,
另一个代码在编译时运行。这尤其适用于if(on)…传统的习惯用法是@eliable scaladoc涵盖了您的常规用例:
final-val-DEBUG
或者它不是编译时常量。顺便说一句,JVM和它的JIT的可能副本通常在消除死代码方面做得相当好,因此最有可能是简单的final-val-DEBUG=false
和def-log(str:String)=if(DEBUG)print(str)
在大多数情况下应该足够了。除了在Predef.assert中间接使用elidable之外,可能没有人使用elidable,但实际上从来不会删除任何内容。与注释中一样,if(DEBUG)
其中标志为final val
(仅限推断类型)或val DEBUG:true=true
可保证简单消除。
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
}
}
}
}
import app.macros.log.{SimpleMacroLogger => log}
object SimpleMacroLoggerDemo extends App {
log.info("Hello")
}