在 C++ 中,我可以写:
#ifdef DEBUG
cout << "Debugging!" << endl;
Scala中有没有等价物?
在 C++ 中,我可以写:
#ifdef DEBUG
cout << "Debugging!" << endl;
Scala中有没有等价物?
传统的成语是@elidable。
scaladoc 涵盖了您的常规用例:
http://www.scala-lang.org/api/current/scala/annotation/elidable.html
C 预处理器 #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
}
}
}
}
与
import app.macros.log.{SimpleMacroLogger => log}
object SimpleMacroLoggerDemo extends App {
log.info("Hello")
}
它的代码要复杂得多,但它的用法更优越:不需要围绕#ifdef/#endif 等。所以它不会弄乱你的代码。
如果您设置为false,宏将完全删除日志记录。
reify 中的任何内容都将进入生成的字节码,其他代码在编译时运行。这尤其适用于if (on) ...。
如果您希望代码仅在某些条件成立时执行,您可以使用标准 if 块:
if (SystemProperties.get("debug.mode").exists(_ == "true") {
println("Debugging!")
}
如果您出于某种原因担心该语句甚至不应该出现在编译输出中,那么您可以使用带有编译时常量表达式的 if 块。在这些情况下,javac/scalac 将正确推断条件永远不会为真,因此甚至不包括块的字节码。(显然你需要修改你的构建,为调试构建引入一个常量“true”,为 prod 构建引入一个常量“false”。)
object Constants {
final val DEBUG = false
}
// ...
if (Constants.DEBUG) {
println("Debugging!")
}