6

在 C++ 中,我可以写:

#ifdef DEBUG
cout << "Debugging!" << endl;

Scala中有没有等价物?

4

3 回答 3

10

传统的成语是@elidable。

scaladoc 涵盖了您的常规用例:

http://www.scala-lang.org/api/current/scala/annotation/elidable.html

于 2013-05-29T17:28:18.040 回答
7

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) ...

于 2013-05-29T17:25:47.977 回答
-1

如果您希望代码仅在某些条件成立时执行,您可以使用标准 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!")
}
于 2013-05-29T16:51:43.727 回答